Qu'est-ce que c'est (( ))?

90

En parcourant le code source du compilateur gcc (gcc / c-family / c-pragma.c), je vois:

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

et même si j'ai beaucoup d'années de programmation C derrière moi, ces bits: (())me sont encore totalement inconnus. Quelqu'un peut-il expliquer ce qu'ils signifient? Google ne semble pas le trouver.

Ferenc Deak
la source
Et qu'est-ce que c'est GTY? Ce n'est pas défini dans la norme de langue. Consultez votre code.
Alexey Frunze
7
GTY est-il une macro ???
Anshul
1
Vous pouvez le trouver sur Google en spécifiant le site dans la chaîne de requête comme suit:GTY site:gcc.gnu.org
ericson

Réponses:

81

Ils sont «magiques» internes à GCC, c'est-à-dire qu'ils font partie de l'implémentation du compilateur elle-même.

Voir cette page qui parle de leur utilisation. La macro est utilisée pour marquer les types à des fins de garbage collection. Il peut aussi y avoir des arguments, voir cette page pour plus de détails.

UPDATE :: Comme indiqué par Drew Dorman dans un commentaire, la double parenthèse réelle ne fait pas partie de l '"intériorité" de l'implémentation GNU; ils sont couramment utilisés lorsque vous souhaitez rassembler une liste complète d'arguments en un seul argument pour la macro appelée. Cela peut parfois être utile lors de l'emballage, par exemple printf(). Voir cette question, pour en savoir plus sur cette technique .

se détendre
la source
5
L'explication @Krishnabhadra peut être trouvée sur le site lié. De plus amples explications sur les caractéristiques du CCG liées au marqueur GTY imo sortiraient du cadre de cette question et réponse particulière.
Arne Mertz
30
(())lui-même n'est pas de la magie gcc. Il permet à un texte contenant des virgules d'être passé à une macro en tant qu'argument unique. Pour tout compilateur C / C ++.
Drew Dormann
45

En général, il est utilisé avec des macros pour protéger les virgules. Étant donné que #define foo(a,b)l'invocation de macro foo(1,2,3)serait illégale. L'utilisation d'une paire supplémentaire de parenthèses clarifie quelle virgule est protégée: foo((1,2),3)versus foo(1,(2,3)).

Dans ce cas, le GTYpeut prendre plusieurs arguments, séparés par des virgules, mais toutes ces virgules doivent être protégées. C'est pourquoi l'intérieur ()entoure tous les arguments.

MSalters
la source
2
Pouvez-vous expliquer pourquoi quelqu'un devrait utiliser un tel appel?
swaechter
5
Par exemple #define PRINT_A_LOT(a,b) printf("prefix\n"); printf a; printf("infix\n"); printf b; printf("suffix\n");(en C ++, il existe de meilleures solutions que les macro, bien sûr).
MSalters
@Albertus: ce serait également bien si vous transmettez des modèles à une macro Macro((Pair<int, int>), ...). Bien que vous ayez alors des problèmes supplémentaires, vous vous débarrassez de la parenthèse dans la macro
BeniBela