C++ 借助gdb调试宏

C++ 借助gdb调试宏,c++,macros,gdb,C++,Macros,Gdb,我知道另一种方法是将宏转换为内联函数,这将允许gdb单步执行 但我想知道是否有任何方法可以像使用任何其他函数一样使用gdb调试宏定义的每一行 e、 g.在下面的代码片段中 #define print_macro printf("We're inside the macro now");\ for(int i=0; i<100; i++) \ { \ if(i%2 == 0) \ printf("%d is even num

我知道另一种方法是将宏转换为内联函数,这将允许gdb单步执行

但我想知道是否有任何方法可以像使用任何其他函数一样使用gdb调试宏定义的每一行

e、 g.在下面的代码片段中

#define print_macro printf("We're inside the macro now");\
     for(int i=0; i<100; i++) \
     { \
          if(i%2 == 0) \
              printf("%d is even number", i); \
          else \
              printf("%d is odd number);\
     }

int main()
{
    print_macro;
    return 0;
}
#定义print#u宏printf(“我们现在在宏中”)\

对于(int i=0;i而言,调试困难是应避免使用宏的原因之一。不,不能逐行调试宏命令,不能在宏中设置断点,不能在宏中查看变量值等。原因至少有两个:

技术。编译器对宏扩展一无所知。在调用编译器之前,所有宏都由预处理器进行扩展。编译器将无法添加用于寻址宏行的调试信息,因为编译器没有这些信息!因此调试器只能假设预处理器的具体执行方式中国的宏观扩张

<>强>逻辑< /强>。输出C++命令不一定对应于一宏的结构。在结构和语法上,宏代码绝对不能像C++代码。这种只行的宏调试似乎只适用于像您这样的简单示例,其中C++代码容易被查看。(很容易为您,而不是为调试器!)但是考虑一个更复杂的例子。在这个示例中,什么样的调试器应该指出?我认为<代码>赋值(var(int,i),10);< /Cord>唯一的逻辑选项。

#define INT int
#define VAR(TYPE, NAME)  TYPE NAME
#define ASSIGN(V, VAL) V = VAL

ASSIGN(VAR(INT, i), 10);

您不能将宏作为С++代码进行调试,因为它们不是直接的С++代码!但是,您可以按照建议展开宏进行调试。如果您需要类似宏的灵活性,但没有调试问题,请使用模板函数。

您不能单步执行宏,但可以使用
-E
标志查看宏扩展到什么:

g++ main.cpp -E | less

查看gdb命令:

gdb> macro expand *expression using macros*
gdb> info macro *macro name*
根据您的g++版本,您可能需要将-ggdb3添加到compile命令中


如果一个宏被多次定义,
info macro
默认情况下将显示在当前位置应用的宏。
info macro-all…
列出了可能的替代方案。

由于您已经进入调试阶段,print\u宏已经被替换为它的相应值。不再存在print_宏在程序编译和运行后运行。调试打印应该可以工作,但调试器在宏扩展之前无法区分宏中的行和源代码中的行。假设它足够聪明,但为什么要在宏不好的情况下支持它呢?在使用宏之前,用实际函数替换宏当然,我们并不是在询问问题的人。当然,我们可以将宏代码(有一定的局限性)扩展到C++代码,然后调试它。但是这是对最终C++代码的调试,而不是宏。此外,调试器只预测预处理器的行为。(如文档中所述)。例如,调试器对使用的编译标志一无所知,这很容易破坏宏扩展的逻辑