为什么即使在我手动运行预处理器之后gdb也会用宏显示我的代码?

时间:2013-12-15 23:20:32

标签: c macros

很抱歉,如果这个问题措辞不当,但这是一个奇怪的问题,我不确定如何解释它。我写了一些涉及宏的愚蠢代码有一个愚蠢的错误,但即使我解决了这个问题,gdb也没有多大帮助。我认为问题可能在于我如何编写宏(它不是),所以我使用了-E标志,所以我可以检查代码并在没有宏的情况下调试它。然后发生了这件事:

/media/sf_Mint-Shared/C $ clang switch.c -E > switch_e.c
/media/sf_Mint-Shared/C $ clang switch_e.c -g -O0 -o switch
/media/sf_Mint-Shared/C $ gdb switch

[剪断]

(gdb) run
Starting program: /media/sf_Mint-Shared/C/switch 
Enter your favorite fruit: apple

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7b6f2f2 in ?? () from /lib/x86_64-linux-gnu/libc.so.6
(gdb) l
6   #define SWITCH(t) strcpy(switch_str, t);
7   #define CASE(c, d) if (!strcmp(switch_str, (c))) {d} else
8   #define ELSE(d) {d}
9   #define ENDSWITCH() switch_str = NULL;
10  
11  int main()
12  {
13    char fruit[20];
14  
15    printf("Enter your favorite fruit: ");
(gdb) l 26
21    scanf("%s", fruit);
22    to_lower(fruit);
23  
24    SWITCH(0, fruit)
25    CASE(0, "apple", puts("Apples are delicious!");)
26    CASE(0, "pear", puts("Pears are alright");)
27    CASE(0, "banana", puts("Ew, bananas are gross");)
28    ELSE(puts("Sorry, I don't know that fruit.");)
29    ENDSWITCH(0)
30  

如果不明显,尽管我从完全预处理的源编译了可执行文件,但宏仍然存在。这是进入处理器的(截断的)代码:

// Includes truncated

static char *switch_str;






int main()
{
  char fruit[20];

  printf("Enter your favorite fruit: ");
  scanf("%s", fruit);

  strcpy(switch_str, fruit);
  if (!strcmp(switch_str, ("apple"))) {puts("Apples are delicious!");} else
  if (!strcmp(switch_str, ("pear"))) {puts("Pears are alright");} else
  if (!strcmp(switch_str, ("banana"))) {puts("Ew, bananas are gross");} else
  {puts("Sorry, I don't know that fruit.");}
  switch_str = ((void *)0);

  return 0;
}

即使在预处理之后,原始宏如何保持不变?如何使用它们进行调试?

1 个答案:

答案 0 :(得分:3)

gcc预处理器插入#line指令,以便能够将预处理的行与原始行相关联。 gcc编译器使用这些指令来生成错误消息和调试信息。因此,即使您手动运行预处理器,也会指示gdb查看原始文件以获取源信息。

您可以使用c -P选项来禁止#line指令。