Respostas:
Sim, use as -E -dM
opções em vez de -c. Exemplo (envia-os para stdout):
gcc -dM -E - < /dev/null
Para C ++
g++ -dM -E -x c++ - < /dev/null
Em vez da saída normal, gere uma lista de diretivas `` #define '' para todas as macros definidas durante a execução do pré-processador, incluindo macros predefinidas. Isso fornece uma maneira de descobrir o que é predefinido na sua versão do pré-processador. Supondo que você não possua o arquivo foo.h, o comando
touch foo.h; cpp -dM foo.h
mostrará todas as macros predefinidas.
Se você usar -dM sem a opção -E, -dM será interpretado como sinônimo de -fdump-rtl-mach.
echo | gcc -dM -E -
funciona também no Windows.
cpp -dM -E - < NUL
pode ser usado.
Eu costumo fazer assim:
$ gcc -dM -E - < /dev/null
Observe que algumas definições do pré-processador dependem das opções da linha de comando - você pode testá-las adicionando as opções relevantes à linha de comando acima. Por exemplo, para ver quais opções SSE3 / SSE4 estão ativadas por padrão:
$ gcc -dM -E - < /dev/null | grep SSE[34]
#define __SSE3__ 1
#define __SSSE3__ 1
e compare isso quando -msse4
for especificado:
$ gcc -dM -E -msse4 - < /dev/null | grep SSE[34]
#define __SSE3__ 1
#define __SSE4_1__ 1
#define __SSE4_2__ 1
#define __SSSE3__ 1
Da mesma forma, é possível ver quais opções diferem entre dois conjuntos diferentes de opções de linha de comando, por exemplo, comparar as definições do pré-processador para os níveis de otimização -O0
(nenhum) e -O3
(completo):
$ gcc -dM -E -O0 - < /dev/null > /tmp/O0.txt
$ gcc -dM -E -O3 - < /dev/null > /tmp/O3.txt
$ sdiff -s /tmp/O0.txt /tmp/O3.txt
#define __NO_INLINE__ 1 <
> #define __OPTIMIZE__ 1
Resposta tardia - achei as outras respostas úteis - e queria adicionar um pouco mais.
Como despejo macros de pré-processador provenientes de um arquivo de cabeçalho específico?
echo "#include <sys/socket.h>" | gcc -E -dM -
ou (obrigado a @mymedia pela sugestão):
gcc -E -dM -include sys/socket.h - < /dev/null
Em particular, eu queria ver o que SOMAXCONN foi definido no meu sistema. Eu sei que poderia abrir o arquivo de cabeçalho padrão, mas às vezes tenho que procurar um pouco para encontrar os locais dos arquivos de cabeçalho. Em vez disso, posso apenas usar esta linha:
$ gcc -E -dM -include sys/socket.h - < /dev/null | grep SOMAXCONN
#define SOMAXCONN 128
$
A abordagem simples ( gcc -dM -E - < /dev/null
) funciona bem para o gcc, mas falha no g ++. Recentemente, eu exigi um teste para um recurso C ++ 11 / C ++ 14. As recomendações para seus nomes de macro correspondentes estão publicadas em https://isocpp.org/std/standing-documents/sd-6-sg10-feature-test-recommendations . Mas:
g++ -dM -E - < /dev/null | fgrep __cpp_alias_templates
sempre falha, porque chama silenciosamente os drivers C (como se invocados por gcc
). Você pode ver isso comparando sua saída com a do gcc ou adicionando uma opção de linha de comando específica para g ++ como (-std = c ++ 11) que emite a mensagem de erro cc1: warning: command line option ‘-std=c++11’ is valid for C++/ObjC++ but not for C
.
Como o gcc (que não é C ++) nunca suporta "Aliases de modelos" (consulte http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2258.pdf ), você deve adicionar a -x c++
opção a forçar a invocação do compilador C ++ (créditos para usar as -x c++
opções em vez de um arquivo fictício vazio, vá para yuyichao, veja abaixo):
g++ -dM -E -x c++ /dev/null | fgrep __cpp_alias_templates
Não haverá saída porque o g ++ (revisão 4.9.1, o padrão é -std = gnu ++ 98) não habilita os recursos do C ++ 11 por padrão. Para fazer isso, use
g++ -dM -E -x c++ -std=c++11 /dev/null | fgrep __cpp_alias_templates
que finalmente rende
#define __cpp_alias_templates 200704
observando que o g ++ 4.9.1 suporta "Aliases de modelos" quando chamado com -std=c++11
.
-x
argumento, portanto g++ -x c++ -dM -E -std=c++11 - < /dev/null | grep cpp
deve funcionar.
Uma abordagem portátil que funciona igualmente bem no Linux ou Windows (onde não há / dev / null):
echo | gcc -dM -E -
Para c ++, você pode usar (substitua c++11
pela versão que usar):
echo | gcc -x c++ -std=c++11 -dM -E -
Ele funciona dizendo ao gcc para pré-processar o stdin (produzido pelo echo) e imprimir todas as definições do pré-processador (procurar -dletters
). Se você deseja saber o que define são adicionados quando você inclui um arquivo de cabeçalho, pode usar a -dD
opção semelhante a -dM, mas não inclui macros predefinidas:
echo "#include <stdlib.h>" | gcc -x c++ -std=c++11 -dD -E -
Observe, no entanto, que a entrada vazia ainda produz muitas definições com a -dD
opção
NUL
, estará de volta à estaca zero: ele não funcionará em sistemas que não o possuem.
sort
se comporte um pouco diferente):echo | gcc -x c++ -std=c++17 -dM -E - | sort
Enquanto trabalhamos em um grande projeto que possui um sistema de compilação complexo e onde é difícil obter (ou modificar) o comando gcc / g ++ diretamente, há outra maneira de ver o resultado da expansão de macro. Redefina simplesmente a macro e você obterá uma saída semelhante à seguinte:
file.h: note: this is the location of the previous definition
#define MACRO current_value