编译超出预处理器阶段但在组装阶段之前

时间:2012-02-14 02:58:33

标签: c gcc compilation macros c-preprocessor

想象一下,程序中有一组宏(macrotest.c),如下所示:

#include <stdio.h>
#include <stdlib.h>
#define n1 75
#define n2 90
#define mac(x,y) ((x > y) ? (12) : (15))

int main(){

   printf("%d",mac(n1,n2));
   exit(0);
}

当你编译成程序集(EM64T)时,你会得到以下结果:

gcc -S -o macrotest.asm macrotest.c

main:
.LFB0:
    .cfi_startproc
    pushq   %rbp
    .cfi_def_cfa_offset 16
    .cfi_offset 6, -16
    movq    %rsp, %rbp
    .cfi_def_cfa_register 6
    movl    $.LC0, %eax
    movl    $15, %esi   <------ This
    movq    %rax, %rdi
    movl    $0, %eax
    call    printf
    movl    $0, %edi
    call    exit
    .cfi_endproc

你可以看到它立即将mac(n1,n2)转换为15。 但是,当您编译到预处理器阶段时,它只会扩展宏:

gcc -E -o macrotest.prp macrotest.c

int main(){

   printf("%d",((75 > 90) ? (12) : (15)));
   exit(0);
}

有没有什么方法可以进一步细分 C 代码而无需进入汇编?

1 个答案:

答案 0 :(得分:3)

尝试选项-fdump-tree-all,看看是否能告诉您需要什么?

这会转储编译器的内部表示形式。它不使用C代码(你不能接受它并编译它),但它看起来有点像C.如果你想了解它更多,请阅读'单一静态分配'(SSA)。

如果您想进一步采用汇编程序,请添加-fdump-rtl-all。对于过程的后半部分,GCC从SSA格式切换(编译器尝试优化程序),并使用它所谓的“寄存器传输语言”。此阶段的目的是优化低级机器指令的使用。这更难理解。尝试阅读GCC内部手册。