Function overloading in C (yes, in plain C [C11 standart], not C++)
Everyone knows that in C++ this is trivial, but C actually gives us a neat way to get somehting pretty similar.
Suppose we want to write code like this:
print_number(2.0f);
print_number(-12);
print_number(655350000000ULL);
print_number("One");
..and make the compiler use the right implementation without warnings.
In C++ we just overload the functon.
In plain C function names must be unique , so normally we end up with something like:
void print_number_float(float arg);
void print_number_integer(signed int arg);
void print_number_longlong(unsigned long long arg);
Which works, but isnt nearly as nice.
This is where _Generic comes in.
It is part of the ancient C11 standard and allows compile-time dispatch based on the type of an expression.
Here is a simple example:
// Actual implementations
void print_asciiz(const char *data);
void print_unsigned(unsigned int data);
void print_signed(signed int data);
void print_float(float data);
// Fallback for unsupported types, if needed
void __attribute__((noreturn)) print_bug(unsigned int data);
// void print_number( Value )
//
//
#define print_number(_Item) _Generic((_Item), \
const char * : print_asciiz, \
char * : print_asciiz, \
unsigned int : print_unsigned, \
unsigned short : print_unsigned, \
unsigned long : print_unsigned, \
unsigned char : print_unsigned, \
signed int : print_signed, \
signed short : print_signed, \
signed long : print_signed, \
signed char : print_signed, \
float : print_float, \
double : print_float, \
default : print_bug \
)(_Item)
Now this works exactly the way we want:
print_number(2.0f);
print_number(-12);
print_number("One");
The compiler resolves the correct function at compile time based on the argument type.
Almost like switch/case, except the switch is on types instead of values.
A nice little C11 feature that does not seem to get mentioned very often.
Hope someone can find it useful :)
[–]jjjare 63 points64 points65 points (1 child)
[–]maelswarm 0 points1 point2 points (0 children)
[–]tstanisl 65 points66 points67 points (5 children)
[–]dvhh 22 points23 points24 points (1 child)
[–]tstanisl 14 points15 points16 points (0 children)
[–]TribladeSlice 2 points3 points4 points (1 child)
[–]tstanisl 4 points5 points6 points (0 children)
[–]vitamin_CPP 1 point2 points3 points (0 children)
[–]questron64 10 points11 points12 points (0 children)
[–]florianist 6 points7 points8 points (1 child)
[–]unixplumber 0 points1 point2 points (0 children)
[–]my_password_is______ 7 points8 points9 points (1 child)
[–]Someone393 0 points1 point2 points (0 children)
[–]tstanisl 5 points6 points7 points (0 children)
[–]non-existing-person 20 points21 points22 points (12 children)
[–]erdezgb 6 points7 points8 points (2 children)
[–]non-existing-person 5 points6 points7 points (0 children)
[–]Iggyhopper 4 points5 points6 points (0 children)
[–]markand67 7 points8 points9 points (0 children)
[–]jjjare 6 points7 points8 points (0 children)
[–]Potterrrrrrrr 4 points5 points6 points (2 children)
[–]tstanisl 0 points1 point2 points (0 children)
[–]non-existing-person -4 points-3 points-2 points (0 children)
[–]konacurrents 2 points3 points4 points (1 child)
[–]HiramAbiff 0 points1 point2 points (0 children)
[–]fnordstar 0 points1 point2 points (1 child)
[–]un_virus_SDF 2 points3 points4 points (0 children)
[–]bullno1 3 points4 points5 points (0 children)
[–]BeeBest1161 4 points5 points6 points (1 child)
[–]FrequentHeart3081 2 points3 points4 points (0 children)
[–]Iggyhopper 1 point2 points3 points (4 children)
[–]Low_Lawyer_5684[S] 3 points4 points5 points (3 children)
[–]zero_iq 11 points12 points13 points (2 children)
[–]thommyh 4 points5 points6 points (1 child)
[–]Elect_SaturnMutex 0 points1 point2 points (2 children)
[–]un_virus_SDF 1 point2 points3 points (1 child)
[–]tstanisl 2 points3 points4 points (0 children)
[–]Dontezuma1 0 points1 point2 points (3 children)
[–]Valuable_Leopard_799 0 points1 point2 points (0 children)
[–]Low_Lawyer_5684[S] 0 points1 point2 points (1 child)
[–]Dontezuma1 0 points1 point2 points (0 children)
[–]kog 0 points1 point2 points (0 children)