سؤال

This question is closely related to a subsequently asked question here.

The method of defining in-class constants is described here by Stroustrup.

When I follow Stroustrup's method I see the expected results. However, in Visual Studio 2010, the debugger cannot resolve a static const class member within that class's scope. Here is what I mean:

#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();
}

When the debugger is in showA() the "watch" window reports:

Error: Symbol "Foo::A" not found

I'd like to emphasize that the program does behave as expected i.e. the output is:

showA = 50

and the program returns 0.

Can anyone else reproduce this with Visual Studio 2010? Is this a bug in the debugger?

هل كانت مفيدة؟

المحلول 3

Visual C++ erroneously provides a weak definition (evidence provided in this answer) based on the declaration inside the class, despite clear language in the Standard:

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.

According to the another rule in the Standard, no definition is needed if the member isn't odr-used.

Whether there's an explicit definition or weak definition erroneously provided by Visual C++ makes no difference however. If the member isn't odr-used, the linker will not see any references to it and will remove it, leaving the debugger confused about whether it ever existed. With the Microsoft linker, you can inhibit this optimization using /OPT:NOREF.

Ultimately that's not something you want to do in production code, though, since you'll have all kinds of vestigial stuff from the standard library left over in your application. But for temporary use during debugging that's a reasonable setting.

نصائح أخرى

You could add a definition for your static data member at global namespace scope:

const int Foo::A;

Adding the static data member definition, which is not necessary but allowed, seems to solve your problem.

I tested this on a debug build with VS2010, and the value of A is correctly displayed in the debug window when the definition is present (while an error message is reported when the definition is missing, consistently with what you mention).

This isn't a bug. The compiler can (and almost always will) optimize out static constant basic types. Instead of allocating storage for A, the compiler is just inlining the value of A into the compiled instructions.

Because A isn't stored anywhere, it has no address, so the debugger cannot view it.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top