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

To compile code in C and C ++, I use this in several 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 completely unnecessary, but in C ++ it void *implicitly advances to char *, and an error is thrown if the listing is missing.

It is also good when I can compile with -std=gnu11in GCC or Clang, but what when I want to make my code compile as ISO C11? I thought I could use C11 _Genericfor implementation typeof(x)to create 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 specified in the declaration a,

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 the string expands fine:

short a = (_Generic((a), short: (short ), char: (char ), char*: (char *), default: (void *) )) 1;                             ^

- , , C _Generic?

+4
2

, . :

#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;
}
+2

, . ( , - , !)

_Generic

type-name: -

default: -

-, . , _Generic , . .

, , C.

+3

Source: https://habr.com/ru/post/1658275/


All Articles