Why C doesn't allow taking the address of a static data member when the data member is initialize within the class and doesn't have an out-of-class definition? How is the storage allocated for static member in this case?
The below minimum program demonstrate the issue.
#include <iostream>
class Test {
public:
static const int a = 99; // how is the storage allocated for Test::a??
};
// const int Test::a;
int main() {
std::cout << Test::a << '\n'; // OK, print 99
const int* ptr = &Test::a; // Linker error, undefined reference to Test::a
}
If I uncomment the line const int Test::a
, then the program works fine.
CodePudding user response:
This line is a declaration:
static const int a = 99;
It is not a definition. For storage to be allocated, you need a definition. That's where your commented line comes into play.
You can use Test::a
even if it has no definition because it is treated as a compile-time constant. In general, a static const T
variable (where T
is a trivial type) must be usable in a constant expression as soon as it is constant-initialized.
Note that you can get both behaviors (compile-time constant and variable with an address) at the same time:
class Test {
public:
static const int a = 99;
};
const int Test::a;
template<int i>
struct Templated {};
int main() {
const int* ptr = &Test::a;
Templated<Test::a> a;
}
And to illustrate the constant-initialization point:
class Test {
public:
static const int a;
};
template<int i>
struct Templated {};
// does not compile because Test::a is *not yet* usable in a constant expression
Templated<Test::a> global;
const int Test::a = 99;
int main() {
const int* ptr = &Test::a;
Templated<Test::a> a;
}