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?
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.