C:const初始化器和调试符号

Nei*_*ill 5 c const declaration

在代码审查中,我要求使用下面的选项(1),因为它导致创建符号(用于调试),而(2)和(3)似乎至少对gcc和icc没有这样做.但是(1)不是真正的const,不能在所有编译器上用作数组大小.有没有更好的选项,包括调试符号,真的是C的常量?

符号:

gcc f.c -ggdb3 -g ; nm  -a a.out | grep _sym
0000000100000f3c s _symA
0000000100000f3c - 04 0000 STSYM _symA
Run Code Online (Sandbox Code Playgroud)

码:

static const int symA = 1;  // 1

#define symB 2 // 2

enum { symC = 3 }; // 3
Run Code Online (Sandbox Code Playgroud)

GDB输出:

(gdb) p symA
$1 = 1

(gdb) p symB
No symbol "symB" in current context.

(gdb) p symC
No symbol "symC" in current context.
Run Code Online (Sandbox Code Playgroud)

而为了完整性,来源:

#include <stdio.h>

static const int symA = 1;

#define symB 2

enum { symC = 3 };

int main (int   argc, char *argv[])
{
    printf("symA %d symB %d symC %d\n", symA, symB, symC);
    return (0);
}
Run Code Online (Sandbox Code Playgroud)

小智 2

-ggdb3选项应该为您提供宏调试信息。但这是一种不同类型的调试信息(它必须不同 - 它告诉调试器如何扩展宏,可能包括参数以及 and#运算##符),因此您无法使用nm.

如果您的目标是让某些内容出现在 中nm,那么我想您不能使用宏。但这是一个愚蠢的目标。你应该想要有一些可以在调试器中实际工作的东西,对吗?尝试print symC一下gdb看看是否有效。

由于宏可以重新定义,gdb因此需要将程序停在宏存在的位置,以便找到正确的定义。在这个程序中:

#include <stdio.h>
int main(void)
{
  #define X 1
  printf("%d\n", X);
  #undef X
  printf("---\n");
  #define X 2
  printf("%d\n", X);
}
Run Code Online (Sandbox Code Playgroud)

如果你打破了第一个printfprint X你就会得到 1;next到第二个printfgdb会告诉你没有Xnext再次,它会显示 2。

此外,如果是一个带有参数的宏,并且您希望查看其定义而不是使用一组特定的参数对其进行扩展,则该gdb命令info macro foo也很有用。foo如果宏扩展为非表达式的内容,gdb那么printinfo macro是您唯一可以用它做的事情。

为了更好地检查原始调试信息,请尝试objdump -W代替nm.