Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

c

gcc

generics

gnu

c11

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?

like image 755
cat Avatar asked Oct 20 '16 00:10

cat


People also ask

What is _generic in C?

_Generic keyword in C is used to define MACRO for different data types. This new keyword was added to the C programming language in C11 standard release. the _Generic keyword is used to help the programmer use the MACRO in a more efficient way. this keyword translate the MACRO based on the type of the variable.

What is typeof in C?

The typeof keyword is a new extension to the C language. The Oracle Developer Studio C compiler accepts constructs with typeof wherever a typedef name is accepted, including the following syntactic categories: Declarations. Parameter type lists and return types in a function declarator. Type definitions.


1 Answers

No, it's not possible. (Now watch someone prove me wrong!)

In a _Generic expression, each generic-association is either

type-name : assignment-expression

or

default : assignment-expression

It can't be a type name or something that expands to a type name. In particular, though a _Generic expression is resolved at compile time, it is not a macro. The final result is always an expression.

And I don't believe there's any other way to do what you want in standard C.

like image 109
Keith Thompson Avatar answered Oct 13 '22 06:10

Keith Thompson