Как я могу передать тип или значение _Generic()

#c #macros

#c #макросы

Вопрос:

sizeof Встроенный модуль может принимать либо тип, либо выражение и возвращает соответствующее значение.

Я хотел бы создать макрос, который использует _Generic() выражения для выполнения чего-то подобного. В частности, я хотел бы иметь возможность передавать либо имя типа, либо значение в качестве параметра, точно так же, как sizeof .

В качестве тривиального примера я могу сделать что-то вроде этого:

 #define F(x) _Generic((x) 0, int: 1, long: 2)  

Это работает, потому (x) 0 что может быть либо арифметическим выражением, либо приведением типа.

  • (1) 0 -gt; 1 0 -gt;gt; 1 -gt;gt;gt; int: 1
  • (длинный) 0 -gt; 0L -gt;gt; длинный: 2

Но это не работает, когда тип есть struct Foo .

Я мог бы использовать составной синтаксис литералов с фигурными скобками: (x){0} но это не подходит для литеральных значений:

  • (длинный){0} — работает
  • (структура Foo){0} — работает
  • (1){0} — не так много. 🙁

Существует ли какой-то извращенный синтаксический ужас C, который позволит использовать имена типов или выражения в a _Generic -выражении?

Комментарии:

1. Да, но _Generic((x) 0, int: 1, long: 2) обрабатывает только 2 двух типа. Если вы хотите, это обрабатывать больше типов, таких как struct foo , double , char * ,… Вам понадобятся эти типы в вашем _Generic списке.

Ответ №1:

Ваша сложная буквальная идея сработает, если вы объедините ее с typeof . Однако обратите внимание, что typeof это расширение языка C GCC, поэтому оно может работать не в каждом компиляторе C.

 #include lt;stdio.hgt;  typedef struct Foo {  int mx; } Foo;  #define F(x) _Generic((typeof(x)){0},   int: 1,   long: 2,   struct Foo: 3)  int main() {  printf("%dn", F(0)); // 1  printf("%dn", F(int)); // 1  printf("%dn", F((long)0)); // 2  printf("%dn", F(long)); // 2  printf("%dn", F((Foo){1})); // 3  printf("%dn", F(Foo)); // 3 }  

Комментарии:

1. » typeof-это расширение языка GCC C » Да, и, надеюсь, оно будет официально благословлено C23