预处理器输出

35 macros gcc c-preprocessor

在将C预处理器转换为目标文件之前,如何查看C预处理器生成的输出?

我想看看MACRO定义对我的代码做了什么.

Fai*_*roz 55

gcc -E file.c
Run Code Online (Sandbox Code Playgroud)

要么

g++ -E file.cpp
Run Code Online (Sandbox Code Playgroud)

会为你做这件事.-E开关强制编译器在预处理阶段之后停止,将此刻所有内容吐出到标准输出.

注意:当然你必须有一些#include指令.包含的文件也会得到预处理,因此您可能会获得大量输出.

对于Visual C++,开关是/ E,它将预处理器输出吐出到屏幕.

  • `gcc -E -nostdinc`将绕过标准的#include文件 (24认同)
  • `-P` 标志将禁止生成线标记。 (4认同)
  • 如果您正在处理的文件没有标准的 c 扩展名,您可能还需要指定 `-xc` (3认同)
  • 您可能需要指定 `-I` 和 `-D` 开关。 (2认同)

Bar*_*nau 7

这取决于您使用的编译器。
使用 GCC,您可以-E在命令行上指定标志,让编译器生成预处理器输出。


rda*_*das 7

您也可以直接调用C预处理器.

cpp infile outfile
Run Code Online (Sandbox Code Playgroud)

查看man cpp更多信息.


小智 5

对于GCC,

gcc -E -dM file.c
Run Code Online (Sandbox Code Playgroud)

要么

g++ -E -dM file.cpp
Run Code Online (Sandbox Code Playgroud)

应该做的工作.-dM,正如GNU预处理器手册所说,它应该为执行预处理器期间定义的所有宏生成一个'#define'指令列表,包括预定义的宏.


Cir*_*四事件 5

-save-temps

该选项的一大优点-E是可以很容易地将其添加到任何构建脚本中,而不会过多干扰构建本身:

gcc -save-temps -c -o main.o main.c
Run Code Online (Sandbox Code Playgroud)

主程序

#define INC 1

int myfunc(int i) {
    return i + INC;
}
Run Code Online (Sandbox Code Playgroud)

现在,除了正常的输出之外main.o,当前工作目录还包含以下文件:

  • main.i是一个包含所需的预处理文件:

    # 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;
    }
    
    Run Code Online (Sandbox Code Playgroud)
  • main.s是一个额外的好处,并且包含所需的生成程序集:

        .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
    
    Run Code Online (Sandbox Code Playgroud)

-save-temps=obj

如果您想对大量文件执行此操作,请考虑改用:

gcc -save-temps -c -o main.o main.c
Run Code Online (Sandbox Code Playgroud)

它将中间文件保存到与-o对象输出相同的目录而不是当前工作目录,从而避免潜在的基本名称冲突。

例如:

gcc -save-temps -c -o out/subdir/main.o subdir/main.c
Run Code Online (Sandbox Code Playgroud)

导致文件的创建:

out/subdir/main.i
out/subdir/main.o
out/subdir/main.s
Run Code Online (Sandbox Code Playgroud)

显然,苹果公司正在密谋占领世界。

-save-temps -v

关于此选项的另一个很酷的事情是如果您添加-v

#define INC 1

int myfunc(int i) {
    return i + INC;
}
Run Code Online (Sandbox Code Playgroud)

它实际上显示了正在使用的显式文件,而不是下的丑陋的临时文件/tmp,因此很容易准确地知道发生了什么,其中包括预处理/编译/组装步骤:

# 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;
}
Run Code Online (Sandbox Code Playgroud)

在 Ubuntu 22.10 amd64、GCC 8.3.0 中测试。