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

use*_*130 8 c++ compiler-construction gcc debuggervisualizer visual-studio

这个问题与此后提出的问题密切相关.

Stroustrup 在这里描述了定义类内常量的方法.

当我按照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();
}
Run Code Online (Sandbox Code Playgroud)

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

Error: Symbol "Foo::A" not found
Run Code Online (Sandbox Code Playgroud)

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

showA = 50
Run Code Online (Sandbox Code Playgroud)

并且程序返回0.

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

And*_*owl 7

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

const int Foo::A;
Run Code Online (Sandbox Code Playgroud)

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

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


Ben*_*igt 2

尽管标准中有明确的语言,但Visual C++根据类内部的声明错误地提供了弱定义(本答案中提供的证据) :

\n\n
\n

静态数据成员在其类定义中的声明不是定义,并且可能是除 cv 限定之外的不完整类型void。静态数据成员的定义应出现在包含 member\xe2\x80\x99s 类定义的命名空间范围中。在命名空间范围的定义中,静态数据成员的名称应使用运算符由其类名限定::

\n
\n\n

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

\n\n

然而,无论 Visual C++ 错误地提供显式定义还是弱定义,都没有什么区别。如果该成员不是odr-used,链接器将看不到任何对它的引用,并将删除它,使调试器对它是否曾经存在感到困惑。通过 Microsoft 链接器,您可以使用/OPT:NOREF.

\n\n

不过,最终这不是您想要在生产代码中执行的操作,因为您的应用程序中会残留标准库中的各种残留内容。但对于调试期间的临时使用来说,这是一个合理的设置。

\n