Luiz Martins
Luiz Martins

Reputation: 1724

`_Generic` with a type as output

_Generic can select between different statements based on the type of the variable passed, however (as somewhat expected) it fails if these statements contain type names themselves. As an example:

#define PROMOTE(var) \ 
    _Generic((var), \
        char: int);

int main() {
   char c;
   PROMOTE(c) i = 0;
   return 0;
}

One might expect the above code to work, with the line using PROMOTE evaluating to "int i = 0", but alas, it does not compile. I tried some roundabout ways to write the type (int), such as with a macro (#define TYPE_int int) or a typedef (typedef int TYPE_int), but to no avail. This is most probably intended (or purposefully undefined) behavior, but I'm still interested in the possibility, even if it requires some C wizardry.

In light of that, how can one make _Generic output a type?

Note: Solutions should rely only on standard C (i.e. no compiler specific constructs).

Upvotes: 3

Views: 692

Answers (1)

tstanisl
tstanisl

Reputation: 14127

The closest thing I can imagine is combination of _Generic, compound literals and typeof extension available in popular compilers like GCC and CLANG.

#include <stdio.h>

struct SomeStruct { int x; };

#define PROMOTE(X) typeof(_Generic((X){0}, char: (int){0}, int: (float){0}, float: (struct SomeStruct){0}))

int main() {
    PROMOTE(char) a = 1;
    PROMOTE(int) b = 2.0f;
    PROMOTE(float) c = { .x = 42 };
    printf("%d\n", a);
    printf("%f\n", b);
    printf("%d\n", c.x);
    return 0;
}

prints

1
2.000000
42

Unfortunately, This is not standard C.

Upvotes: 4

Related Questions