Reputation: 529
Trying to overloading a function in C programming language with _Generic
. Have found examples:
This the example:
#include <stdio.h>
#include <math.h>
void display_float(float dispid) ;
void display_int(int dispid) ;
void display_void(void) ;
#define display(x) _Generic((x), \
float: display_float, \
int: display_int, \
default: display_float \
)(x)
void display_void(void){
printf("display id: 0\n") ;
}
void display_float(float dispid){
printf("display id: %f\n", dispid) ;
}
void display_int(int dispid){
printf("display id: %d\n", dispid) ;
}
void main(void){
display(5) ;
display(6.5) ;
}
Now I also want to overload the function with display()
. Meaning the function would intake a void
, call the function display_void()
, and display 0. Can't seem to do this. Any help would be appreciated.
EDIT 1:
Also, see the examples here. One of the examples (I think) is passing a pointer to a void. Can this be implemented?
Upvotes: 1
Views: 2055
Reputation: 1
Trying to overloading a function in C programming language
C11 does not have any function overloading and _Generic
is for genericity, not for overloading, check that by reading n1570. Consider switching to C++ (or even better, Rust) which provides function overloading. Notice that it is illegal to have a void
(not void*
, just void
) argument to a C function, so there is no any "top" super-type in C, which would be a super type of other types (and this because of calling conventions and ABI considerations making C a low-level programming language, sometimes even called a "portable assembler"). Read more about abstract interpretation and type systems please.
If _Generic
was for overloading, the members of the C11 standard committee - all programming language experts and good enough English writers - would have named it like _Overload
, but they wisely did not.
Food for thought (assuming both stderr
and stdin
works like you want them to work) :
what about some hypothetical display(stderr)
or display(*stdin)
or display("abc")
?
(a wrong suggestion below, followed by a better advice)
(this does not work!)
Your display_void
should take some argument, e.g.
void display_void(void*p) { printf("p@%p\n", p);
Then you might have:
#define display_anything(P) display_void((void*)(&(P)))
with
#define display(x) _Generic((x), \
float: display_float, \
int: display_int, \
default: display_anything \
)(x)
Since that does not work (and it does not), design your code in some other way. For example, consider having some tagged union, like here. Look into GVariant (from Glib) implementation for inspiration.
Upvotes: 1
Reputation: 141493
Sure. Overload Macro on Number of Arguments.
void display_float(float dispid) ;
void display_int(int dispid) ;
void display_void(void) ;
#define _display_1(x) _Generic((x), \
float: display_float, \
int: display_int, \
default: display_float \
)(x)
#define _display_0() display_void()
#define _display_N(_0,_1,N,...) _display_ ## N
#define display(...) _display_N(_0,##__VA_ARGS__,1,0)(__VA_ARGS__)
int main() {
display();
display(1);
display(1.1);
}
Tested on godbolt.
Note that , ##__VA_ARGS__
is a gcc extension not described in the C standard.
Upvotes: 5