Is it possible to implement GNU C's typeof(x) with C11's _Generic?

c, c11, gcc, generics, gnu

Solution

The problem is that you can't have a partial expression inside the generic selection. A possible work-around could be to put a full expression inside it:

#define cast(from, to) _Generic((from), \
  short:       (short) (to),            \
  char:        (char)  (to),            \
  char*:       (char*) (to),            \
  default:     (void*) (to))

int main (void) {
  short a = cast(a, 1);

  return 0;
}

Problem

To make some code compile in C and C++ I use this in a few places: ``` #ifdef __cplusplus #define typeof(x) decltype(x) // works ok in most cases, except C++ reference types #endif char* a = (typeof(a)) malloc(4); ``` In C, this compiles to `char* a = (char *) malloc(4)` where the cast is totally unecessary, but in C++ `void *` is not implicitly promoted to `char *` and an error is issued if a cast is not present. This is just as well when I can compile with `-std=gnu11` on GCC or Clang, but what when I want to make my code compile as ISO C11? I thought I could use C11's `_Generic` to implement `typeof(x)` to cast some types: ``` #define gettype(x) _Generic((x), \ short: (short ), \ char: (char ), \ char*: (char *), \ default: (void *) ) int main (void) { short a = (gettype(a)) 1; return a; } ``` But no matter what type defined in `gettype(x)` is given in `a`'s declaration, ``` typeof.h: In function ‘main’: typeof.h:2:24: error: expected expression before ‘,’ token short: (short ), \ ^ typeof.h:8:13: note: in expansion of macro ‘gettype’ char a = (gettype(a)) 1; ^~~~~~~ typeof.h:8:25: error: expected ‘,’ or ‘;’ before numeric constant char a = (gettype(a)) 1; ``` `gcc -E` says that line expands just fine: ``` short a = (_Generic((a), short: (short ), char: (char ), char*: (char *), default: (void *) )) 1; ^ ``` Is there some syntax I am missing, or is it simply not possible in C to generate cast code using `_Generic`?

Original source

Related problems