Estou usando uma biblioteca de código aberto que parece ter muitas diretivas de pré-processamento para suportar muitas linguagens diferentes de C. Para que eu possa estudar o que a biblioteca está fazendo, gostaria de ver o código C que estou compilando após o pré-processamento , mais parecido com o que eu escreveria.
O gcc (ou qualquer outra ferramenta comumente disponível no Linux) pode ler esta biblioteca, mas gerar o código C que tem o pré-processamento convertido para qualquer coisa e também pode ser lido por um humano?
gcc -E
é mais útil do que reescrever a linha para que funcionecpp
.Respostas:
Sim. Passe a
-E
opção gcc . Isso produzirá código-fonte pré-processado.fonte
-o something.o
você também pode alterá-lo para-o something.i
. Caso contrário, a saída pré-processada estará no.o
arquivo.gcc -E file1.c file2.c ...
cpp
é o pré-processador.Execute
cpp filename.c
para gerar o código pré-processado ou, melhor, redirecioná-lo para um arquivo comcpp filename.c > filename.preprocessed
.fonte
diff
Acontece nenhuma diferença nos arquivos. Essa também parece uma maneira útil de pré-processar o código à procura de erros em suas macros. Ótima pergunta e uma ótima resposta (IALCTHW).Estou usando o gcc como pré-processador (para arquivos html). Ele faz exatamente o que você deseja. Ele expande as diretivas "# -" e produz um arquivo legível. (NONE
gcc -E -xc -P -C -traditional-cpp code_before.cpp> code_after.cpp
(Não precisa ser 'cpp'.) Há uma excelente descrição desse uso em http://www.cs.tut.fi/~jkorpela/html/cpre.html .
O "-traditional-cpp" preserva os espaços em branco e as guias.
fonte
-save-temps
Esta é outra boa opção a se ter em mente:
main.c
e agora, além da saída normal
main.o
, o diretório de trabalho atual também contém os seguintes arquivos:main.i
é o arquivo pré-possuído desejado contendo:main.s
é um bônus :-) e contém o conjunto gerado:Se você quiser fazer isso para um grande número de arquivos, considere usar:
que salva os arquivos intermediários no mesmo diretório da
-o
saída do objeto em vez do diretório de trabalho atual, evitando assim possíveis conflitos de nome de base.A vantagem dessa opção
-E
é que é fácil adicioná-la a qualquer script de construção, sem interferir muito na própria construção.Outra coisa legal sobre essa opção é se você adicionar
-v
:na verdade, ele mostra os arquivos explícitos sendo usados em vez de temporários feios sob
/tmp
, então é fácil saber exatamente o que está acontecendo, o que inclui as etapas de pré-processamento / compilação / montagem:Testado no Ubuntu 19.04 amd64, GCC 8.3.0.
fonte
Corre:
ou
fonte
Suponha que temos um arquivo como Message.cpp ou um arquivo .c
Etapas 1: pré - processamento (argumento -E)
g ++ -E. \ Message.cpp> P1
O arquivo P1 gerado tem macros expandidas e o conteúdo e os comentários do arquivo de cabeçalho são removidos.
Etapa 2: Traduzir o arquivo pré-processado para o assembly (Argumento -S). Esta tarefa é feita pelo compilador
g ++ -S. \ Message.cpp
Um montador (ASM) é gerado (Message.s). Ele contém todo o código de montagem.
Etapa 3: Traduzir o código do assembly para o código do objeto. Nota: Message.s foi gerado na Etapa 2. g ++ -c. \ Message.s
Um arquivo Object com o nome Message.o é gerado. É a forma binária.
Etapa 4: Vinculando o arquivo objeto. Esta tarefa é realizada pelo vinculador
g ++. \ Message.o -o MessageApp
Um arquivo exe MessageApp.exe é gerado aqui.
fonte