Что это (( ))?

90

Просматривая исходный код компилятора gcc (gcc / c-family / c-pragma.c), я вижу:

typedef struct GTY(()) align_stack {
  int                  alignment;
  tree                 id;
  struct align_stack * prev;
} align_stack;

и, несмотря на то, что у меня за плечами много лет программирования на C, эти биты: (())мне еще полностью неизвестны. Может кто-нибудь объяснить, что они означают? Гугл вроде не находит.

Ференц Деак
источник
А это что GTY? Это не определено в языковом стандарте. Смотрите свой код.
Алексей Фрунзе
7
это GTY макрос ???
Аншул
1
Вы можете найти его в Google, указав сайт в строке запроса следующим образом:GTY site:gcc.gnu.org
ericson

Ответы:

81

Это внутренняя «магия» GCC, то есть часть самой реализации компилятора.

См. Эту страницу, где рассказывается об их использовании. Макрос используется для маркировки типов для целей сборки мусора. Также могут быть аргументы, подробности см. На этой странице .

ОБНОВЛЕНИЕ :: Как указал Дрю Дорман в комментарии, фактические двойные скобки не являются частью «внутренней сущности» реализации GNU; они обычно используются, когда вы хотите собрать весь список аргументов в один аргумент для вызываемого макроса. Иногда это может быть полезно, например printf(), при упаковке . См. Этот вопрос, чтобы узнать больше об этой технике .

размотать
источник
5
Объяснение @Krishnabhadra можно найти на связанном сайте. Дальнейшее объяснение функций GCC, связанных с GTY-marker imo, выходит за рамки этого конкретного вопроса и ответа.
Арне Мертц
30
(())сам по себе не является магией gcc. Он позволяет передать макросу текст, содержащий запятые, как один аргумент. Для любого компилятора C / C ++.
Дрю Дорманн,
45

В общем, он используется с макросами для защиты запятых. Учитывая #define foo(a,b), что вызов макроса foo(1,2,3)был бы незаконным. Использование дополнительной пары круглых скобок поясняет, какая запятая экранирована: по foo((1,2),3)сравнению с foo(1,(2,3)).

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

MSalters
источник
2
Вы можете объяснить, почему кто-то должен использовать такой звонок?
Swaechter
5
Например #define PRINT_A_LOT(a,b) printf("prefix\n"); printf a; printf("infix\n"); printf b; printf("suffix\n");(в C ++, конечно, есть более приятные решения, чем макросы).
MSalters
@Albertus: также было бы неплохо, если бы вы передавали шаблоны в макрос Macro((Pair<int, int>), ...). Хотя тогда вы
столкнетесь с