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

时间:2013-05-03 18:59:23

标签: c++ visual-studio gcc compiler-construction debuggervisualizer

此问题与随后提出的问题here.

密切相关

Stroustrup描述了定义类内常量的方法here

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

#include <iostream>

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

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

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

当调试器在showA()中时,“监视”窗口报告:

Error: Symbol "Foo::A" not found

我想强调该程序的行为符合预期,即输出为:

showA = 50

,程序返回0.

其他人可以使用Visual Studio 2010重现这一点吗?这是调试器中的错误吗?

3 个答案:

答案 0 :(得分:7)

您可以在全局命名空间范围内为静态数据成员添加定义

const int Foo::A;

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

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

答案 1 :(得分:3)

这不是错误。编译器可以(并且几乎总是会)优化静态常量基本类型。编译器只是将A的值内联到编译指令中,而不是为A分配存储空间。

由于A未存储在任何地方,因此它没有地址,因此调试器无法查看它。

答案 2 :(得分:2)

Visual C ++基于类中的声明错误地提供a weak definition (evidence provided in this answer),尽管标准中有明确的语言:

  

静态数据成员在其类定义中的声明不是定义,并且可能是cv-qualified void以外的不完整类型。静态数据成员的定义应出现在包含成员类定义的命名空间范围内。在命名空间范围的定义中,静态数据成员的名称应使用::运算符通过其类名进行限定。

根据标准中的另一条规则,如果该成员不是 odr-used ,则无需定义。

Visual C ++错误地提供的显式定义或弱定义是否有所不同。如果该成员不是 odr-used ,则链接器将不会看到对它的任何引用并将其删除,从而使调试器对它是否存在感到困惑。使用Microsoft链接器,您可以使用/OPT:NOREF禁止此优化。

最终,这不是你想要在生产代码中做的事情,因为你将在应用程序中遗留标准库中的所有类型的遗留物。但是在调试期间暂时使用这是一个合理的设置。