关于c ++:为什么Visual Studio 2010调试器不能看到静态const类成员?

Why Doesn't the Visual Studio 2010 Debugger See static const Class Members?

这个问题与随后提出的问题密切相关。

类常量的定义方法在这里由stroustrup描述。

当我遵循stroustrup的方法时,我看到了预期的结果。但是,在Visual Studio 2010中,调试器无法解析该类范围内的static const类成员。我的意思是:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>

class Foo {
   public:
    static const int A = 50;
    char arr[A];
    void showA();
};

void Foo::showA() {
    std::cout <<"showA =" << A <<"
"
;
}

int main() {
    Foo f;
    f.showA();
}

当调试器在showa()中时,"watch"窗口报告:

1
Error: Symbol"Foo::A" not found

我要强调的是,程序的行为确实如预期,即输出是:

1
showA = 50

程序返回0。

其他人能用Visual Studio 2010复制这个吗?这是调试器中的错误吗?


可以在全局命名空间范围中添加静态数据成员的定义:

1
const int Foo::A;

添加静态数据成员定义(这不是必需的,但允许)似乎可以解决您的问题。

我在使用VS2010的调试版本上对此进行了测试,并且当存在定义时,A的值会正确显示在调试窗口中(当缺少定义时会报告错误消息,与您提到的一致)。


这不是臭虫。编译器可以(几乎总是)优化静态常量的基本类型。编译器不为A分配存储,而只是将A的值嵌入编译的指令中。

因为A没有存储在任何地方,所以它没有地址,所以调试器无法查看它。


Visual C++错误地提供了一个弱定义(在这个答案中提供的证据),基于该类中的声明,尽管标准中有明确的语言:

The declaration of a static data member in its class definition is not a definition and may be of an incomplete type other than cv-qualified void. The definition for a static data member shall appear in a namespace scope enclosing the member’s class definition. In the definition at namespace scope, the name of the static data member shall be qualified by its class name using the :: operator.

根据标准中的另一条规则,如果成员不使用ODR,则不需要定义。

然而,VisualC++中是否有一个明确的定义或弱定义没有区别。如果该成员未使用ODR,则链接器将看不到对它的任何引用,并将删除它,使调试器对它是否存在感到困惑。使用Microsoft Linker,您可以使用/OPT:NOREF来抑制这种优化。

最终,这不是您想要在生产代码中做的事情,但是,因为您将拥有应用程序中遗留下来的标准库中的各种残留内容。但对于调试期间的临时使用,这是一个合理的设置。