DEV Community

PGzlan
PGzlan

Posted on

2

Function overloading in C

Function overloading is regarded as powerful feature in programming languages. It allows developers to define multiple functions that take different arguments while having the same name.

This can be a convenient method of writing code that is more readable, maintainable, and reusable.

In C, function overloading is not a built-in feature, but it can be achieved through a technique called "name mangling" or "function name decoration" (more on that in an upcoming post).

In this post, we will explore some methods that can help us achieve function overloading in C.

Using _Generic keyword/macro

While function overloading is not supported in C, you can achieve similar functionality by using the _Generic keyword, which is available in C11 and later

#include <stdio.h>

#define double_num(x) _Generic((x), \
    int: double_int, \
    float: double_float, \
    long: double_long \
)(x)

int double_int(int num) {
    return num * 2;
}

float double_float(float num) {
    return num * 2.0;
}

long double_long(long num) {
    return num * 2;
}

int main() {
    int v1 = 2;
    float v2 = 3.0f;
    long v3 = 4;

    int x = double_num(v1);
    printf("%d doubled again is %d\n", v1, x);

    float y = double_num(v2);
    printf("%f doubled again is %f\n", v2, y);

    long z = double_num(v3);
    printf("%ld doubled again is %ld\n", v3, z);   

    return 0;

}
Enter fullscreen mode Exit fullscreen mode

Using clang attribute overloadable:

The Clang compiler, compiler that supports multiple programming languages including OpenMP, OpenCL and other framework, has a feature called attributes which are used to declare additional information about the behavior of functions, variables, types, and other language constructs.

The overloadable attribute can be used to achieve function overloading in C.

#include <stdio.h>

__attribute__((overloadable)) int double_num(int num) {
    return num * 2;
}

__attribute__((overloadable)) float double_num(float num) {
    return num * 2.0;
}

__attribute__((overloadable)) long double_num(long num) {
    return num * 2;
}


int main() {
    int v1 = 2;
    float v2 = 3.0f;
    long v3 = 4;

    int x = double_num(v1);
    printf("%d doubled again is %d\n", v1, x);

    float y = double_num(v2);
    printf("%f doubled again is %f\n", v2, y);

    long z = double_num(v3);
    printf("%ld doubled again is %ld\n", v3, z);

    return 0;

}
Enter fullscreen mode Exit fullscreen mode

The overloadable attribute is a Clang-specific extension, so it is not portable to other compilers. This means that if you use this attribute, your code may not compile with other compilers such as GCC or MSVC. There are also some caveats that come with using attributes. If you're interested in knowing more about how they work, be sure to check the link in the references section.

Using varargs

In C, varargs refers to a feature that allows functions to accept a variable number of arguments. This is achieved through the use of the stdarg.h header file, which defines a set of macros for accessing the arguments passed to a function.

A function that uses varargs must include an ellipsis (...) as the last parameter in its parameter list. This indicates that the function can accept additional arguments after the named parameters. The va_list, va_start, va_arg, and va_end macros are then used within the function to access these additional arguments.

#include <stdio.h>
#include <stdarg.h>
#include <string.h>


int double_num(const char* format, ...) {
    va_list args;
    va_start(args, format);
    if (strcmp(format, "%d") == 0) {
        int num = va_arg(args, int);
        va_end(args);
        return num * 2;
    } else if (strcmp(format, "%f") == 0) {
        float num = va_arg(args, double);
        va_end(args);
        return num * 2.0;
    } else if (strcmp(format, "%ld") == 0) {
        long num = va_arg(args, long);
        va_end(args);
        return num * 2;
    }
    va_end(args);
    return 0;
}

int main() {

    int v1 = 2;
    float v2 = 3.0f;
    long v3 = 4;

    int x = double_num("%d", v1);
    printf("%d doubled again is %d\n", v1, x);

    float y = double_num("%f", v2);
    printf("%.2f doubled again is %.2f\n", v2, y);

    long z = double_num("%ld", v3);
    printf("%ld doubled again is %ld\n", v3, z);

    return 0;

}
Enter fullscreen mode Exit fullscreen mode

In a following post, we'll explore more on what this actually translates to in terms of the compile file that runs this code.

Note: All the previous code, apart from the clang one, were built with gcc. The clang one can be built using the same style as gcc. You just have to replace gcc with clang in your command

References

https://clang.llvm.org/docs/AttributeReference.html
https://www.udacity.com/blog/2021/09/cp-function-overloading-what-you-need-to-know.html
https://learn.microsoft.com/en-us/cpp/cpp/function-overloading?view=msvc-170
https://stackoverflow.com/questions/36504216/function-overloading-in-c-without-using-generic
https://stackoverflow.com/questions/64408323/how-to-overload-functions-in-c
Attributes in Clang — Clang 17.0.0git documentation (llvm.org)

Qodo Takeover

Introducing Qodo Gen 1.0: Transform Your Workflow with Agentic AI

Rather than just generating snippets, our agents understand your entire project context, can make decisions, use tools, and carry out tasks autonomously.

Read full post

Top comments (1)

Collapse
 
blueberry077 profile image
Marc-Daniel DALEBA

This is super interesting, I never knew about the two first. You are making me a better C programmer. (°▽°).

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more

AWS GenAI LIVE!

GenAI LIVE! is a dynamic live-streamed show exploring how AWS and our partners are helping organizations unlock real value with generative AI.

Tune in to the full event

DEV is partnering to bring live events to the community. Join us or dismiss this billboard if you're not interested. ❤️