O que é isso (( ))?

90

Ao navegar pelo código-fonte do compilador gcc (gcc / c-family / c-pragma.c), vejo:

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

e apesar de ter muitos anos de programação em C atrás de mim, esses bits: (())são totalmente desconhecidos para mim ainda. Alguém pode explicar o que eles significam? O Google não parece encontrar.

Ferenc Deak
fonte
E o que é isso GTY? Não está definido no padrão de linguagem. Veja seu código.
Alexey Frunze de
7
GTY é uma macro ???
Anshul de
1
Você pode encontrá-lo no Google especificando o site na string de consulta da seguinte forma:GTY site:gcc.gnu.org
ericson

Respostas:

81

Eles são "mágicos" internos do GCC, ou seja, parte da própria implementação do compilador.

Veja esta página que fala sobre seu uso. A macro é usada para marcar tipos para fins de coleta de lixo. Pode haver argumentos também, consulte esta página para obter detalhes.

ATUALIZAÇÃO :: Como apontado por Drew Dorman em um comentário, o parêntese duplo real não faz parte da "internalidade" da implementação GNU; eles são comumente usados ​​quando você deseja coletar uma lista inteira de argumentos em um único argumento para a macro chamada. Isso pode ser útil às vezes ao embrulhar printf(), por exemplo . Veja esta pergunta, para mais informações sobre esta técnica .

desanuviar
fonte
5
A explicação de @Krishnabhadra pode ser encontrada no site vinculado. Explicações adicionais sobre os recursos do GCC relacionados ao marcador GTY imo estariam além do escopo desta pergunta e resposta em particular.
Arne Mertz de
30
(())em si não é mágica do gcc. Ele permite que um texto que inclui vírgulas seja passado para uma macro como um único argumento. Para qualquer compilador C / C ++.
Drew Dormann em
45

Em geral, é usado com macros para proteger vírgulas. Dado #define foo(a,b), a invocação da macro foo(1,2,3)seria ilegal. Usar um par extra de parênteses esclarece qual vírgula está protegida: foo((1,2),3)versus foo(1,(2,3)).

Nesse caso, o GTYpode receber vários argumentos, separados por vírgulas, mas todas essas vírgulas devem ser protegidas. É por isso que o interior ()envolve todos os argumentos.

MSalters
fonte
2
Você pode explicar por que alguém deveria usar essa chamada?
swaechter de
5
Por exemplo #define PRINT_A_LOT(a,b) printf("prefix\n"); printf a; printf("infix\n"); printf b; printf("suffix\n");(em C ++ existem soluções mais agradáveis ​​do que macro, é claro).
MSalters de
@Albertus: também seria bom se você passasse os modelos para uma macro Macro((Pair<int, int>), ...). Embora então você tenha problemas adicionais, livrando-se do parêntese dentro da macro
BeniBela