-1

Lets say I have the following code that initially deals with ints:

#define F_INT(x) _Generic((x), int: f_int(x), int *: f_intptr(x))

void f_int(int x) {printf("int\n");}
void f_intptr(int *x) {printf("intptr\n");}

int main() 
{
    int x;
    F_INT(x);
}

The above code will display "int" because x is declared as an int. If x is declared as pointer to int, the above code will display "intptr". So far so good, even though the code produces warnings.

However if I switch everything to floats, then I get errors. If I declare x as float, I get:

error: incompatible type for argument 1 of ‘f_floatptr’ ... note: expected ‘float *’ but argument is of type ‘float’

If I declare x as float *, I get the opposite error.

_Generic keyword seems to compile type check all selections even though the whole point should be that only one selection is chosen at compile time.

How do I get the above to work. I tried function pointers as a work around, but couldn't work around the issue.

Baddack
  • 1,947
  • 1
  • 24
  • 33
gauth
  • 7
  • 1
  • 2
  • 4
    Can you show the version that has problems? – NetMage Jan 25 '18 at 23:41
  • "*So far so good, even though the code produces warnings.*" -- Don't ignore warnings. I compiled your code (after adding the required `#include ` and got two warnings for things a stricter compiler could have treated as fatal errors (constraint violations). Implicit pointer/floating-point conversions are no more valid than implicit pointer/integer conversions; your compiler (gcc?) just happens to be more lax about the latter. Update your question to show the warnings you get **with the code in the question**, and ask how to fix those warnings. Switching to floats is a red herring. – Keith Thompson Jan 26 '18 at 01:24
  • Only one of the generic-associations in a generic-selection has its expression evaluated, but they're all compiled. See [N1570](http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf) 6.5.1.1. – Keith Thompson Jan 26 '18 at 01:26
  • @NetMage: Actually, he has shown us a version that has problems. He just didn't show us the warnings. – Keith Thompson Jan 26 '18 at 01:27
  • #define F_INT(x) _Generic((x), int : f_int((int) x), int *: f_intptr((int *) x)) fixes the warnings by doing explicit cast. But it does not help with the float version. – gauth Jan 26 '18 at 05:31
  • Sorry I was wrong. The above does not eliminate the warning, just changes it to something else. Anyway the answer from nemequ below seems to work. – gauth Jan 26 '18 at 15:28

1 Answers1

1

Pretty much a duplicate of Incompatible pointer types passing in _Generic macro

You can use something like this instead:

#define F_INT(x) _Generic((x), int: f_int, int *: f_intptr)(x)

Or, if you want to add floats:

#define F_INT(x) _Generic((x), int: f_int, int *: f_intptr, float: f_float, float *: f_floatptr)(x)
nemequ
  • 16,623
  • 1
  • 43
  • 62