Pregunta

Estoy usando una biblioteca de código abierto que parece tener muchas directivas de preprocesamiento para admitir muchos lenguajes además de C. Para poder estudiar lo que está haciendo la biblioteca, me gustaría ver el código C que estoycompilando después del preprocesamiento, más como lo que yo escribiría.

¿Puede gcc (o cualquier otra herramienta comúnmente disponible en Linux) leer esta biblioteca pero generar código C que tiene el preprocesamiento convertido a lo que sea y que también sea legible por un humano?

¿Fue útil?

Solución

Sí.Pase gcc la opción -E.Esto generará código fuente preprocesado.

Otros consejos

cpp es el preprocesador.

Ejecute cpp filename.c para generar el código preprocesado, o mejor, redirigirlo a un archivo con cpp filename.c > filename.preprocessed.

Estoy usando gcc como preprocesador (para archivos html). Hace exactamente lo que quieres.Expande las directivas "# -" y luego genera un archivo legible.(NINGUNO de los otros preprocesadores C / HTML que he intentado hacer esto: concatenan líneas, se ahogan con caracteres especiales, etc.) Suponiendo que tiene instalado gcc, la línea de comando es:

gcc -E -x c -P -C -traditional-cpp code_before.cpp> code_after.cpp

(No tiene que ser 'cpp'.) Hay una excelente descripción de este uso en http://www.cs.tut.fi/~jkorpela/html/cpre.html .

El "-traditional-cpp" conserva los espacios en blanco y las pestañas.

Ejecutar:

gcc -E <file>.c

o

g++ -E <file>.cpp

-save-temps

Esta es otra buena opción a tener en cuenta:

gcc -save-temps -c -o main.o main.c

main.c

#define INC 1

int myfunc(int i) {
    return i + INC;
}

y ahora, además de la salida normal main.o, el directorio de trabajo actual también contiene los siguientes archivos:

  • main.i es el archivo predilecto deseado que contiene:

    # 1 "main.c"
    # 1 "<built-in>"
    # 1 "<command-line>"
    # 31 "<command-line>"
    # 1 "/usr/include/stdc-predef.h" 1 3 4
    # 32 "<command-line>" 2
    # 1 "main.c"
    
    
    int myfunc(int i) {
        return i + 1;
    }
    
  • main.s es una ventaja :-) y contiene el ensamblado generado:

        .file   "main.c"
        .text
        .globl  myfunc
        .type   myfunc, @function
    myfunc:
    .LFB0:
        .cfi_startproc
        pushq   %rbp
        .cfi_def_cfa_offset 16
        .cfi_offset 6, -16
        movq    %rsp, %rbp
        .cfi_def_cfa_register 6
        movl    %edi, -4(%rbp)
        movl    -4(%rbp), %eax
        addl    $1, %eax
        popq    %rbp
        .cfi_def_cfa 7, 8
        ret
        .cfi_endproc
    .LFE0:
        .size   myfunc, .-myfunc
        .ident  "GCC: (Ubuntu 8.3.0-6ubuntu1) 8.3.0"
        .section    .note.GNU-stack,"",@progbits
    

Si desea hacerlo para una gran cantidad de archivos, considere usar en su lugar:

 -save-temps=obj

que guarda los archivos intermedios en el mismo directorio que la salida del objeto -o en lugar del directorio de trabajo actual, evitando así posibles conflictos de nombres de base.

La ventaja de esta opción sobre -E es que es fácil de agregar a cualquier script de compilación, sin interferir mucho en la compilación en sí.

Otra cosa interesante de esta opción es si agrega -v:

gcc -save-temps -c -o main.o -v main.c

En realidad, muestra los archivos explícitos que se utilizan en lugar de feos temporales en /tmp, por lo que es fácil saber exactamente qué está pasando, lo que incluye los pasos de preprocesamiento / compilación / ensamblaje:

/usr/lib/gcc/x86_64-linux-gnu/8/cc1 -E -quiet -v -imultiarch x86_64-linux-gnu main.c -mtune=generic -march=x86-64 -fpch-preprocess -fstack-protector-strong -Wformat -Wformat-security -o main.i
/usr/lib/gcc/x86_64-linux-gnu/8/cc1 -fpreprocessed main.i -quiet -dumpbase main.c -mtune=generic -march=x86-64 -auxbase-strip main.o -version -fstack-protector-strong -Wformat -Wformat-security -o main.s
as -v --64 -o main.o main.s

Probado en Ubuntu 19.04 amd64, GCC 8.3.0.

Supongamos que tenemos un archivo como Message.cpp o un archivo .c

Pasos 1: preprocesamiento (argumento -E)

g ++ -E. \ Message.cpp> P1

El archivo P1 generado tiene macros expandidas y el contenido y los comentarios del archivo de encabezado están eliminados.

Paso 2: Traducir el archivo preprocesado a ensamblado (Argumento -S).Esta tarea la realiza el compilador

g ++ -S. \ Message.cpp

Se genera un ensamblador (ASM) (Message.s).Tiene todo el código ensamblador.

Paso 3: traduzca el código ensamblador al código del objeto.Nota: Message.s se generó en Step2. g ++ -c. \ Message.s

Se genera un archivo de objeto con el nombre Message.o.Es la forma binaria.

Paso 4: vincular el archivo de objeto.Esta tarea la realiza el vinculador

g ++. \ Message.o -o MessageApp

Aquí se genera un archivo exe MessageApp.exe.

#include <iostream>
using namespace std;

 //This a sample program
  int main()
{
cout << "Hello" << endl;
 cout << PQR(P,K) ;
getchar();
return 0;
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top