So, I'm aware that in C++ static members can be initialized inside the class if they are a const literal type like the following
class test{
public:
static constexpr int stc = 1;
private:
int a = 0;
int b = 0;
int c = 0;
};
and the static constexpr variable stc
can be used where the compiler can directly substitute the value of the member i.e
int main () {int array[test::stc];}
However, if used in a context where the value cannot be directly substituted by the compiler:
int main() { const int &cs = test::stc; }
then the compiler (clang) generates an error
c++ -std=c++11 -pedantic t.cpp -o t
Undefined symbols for architecture x86_64:
"test::stc", referenced from:
_main in t-a8ee2a.o
ld: symbol(s) not found for architecture x86_64
unless the static member is defined outside the class like so:
constexpr int test::stc;
Why is this the case?
In
int main() { const int &cs = test::stc; }
test::stc
is odr-used while in
int main () {int array[test::stc];}
it is not.
The following example from the C++11 Standard supports the above idea.
struct S { static const int x = 0; };
const int &f(const int &r);
int n = b ? (1, S::x) // S::x is not odr-used here
: f(S::x); // S::x is odr-used here, so a definition is required
Looking at it from practical point of view, cs
will be an invalid reference unless test::stc
has an address. array
, on the other hand, needs just the value of test::stc
, which can be evaluated at compile time. array
does not need the address of test::stc
to be a valid object.
An object that is odr-used must be defined exactly once in a program.
static constexpr int stc = 1; // declares the static var
constexpr int test::stc; // defines the static var
for more detailed explanation check link below
http://www.learncpp.com/cpp-tutorial/811-static-member-variables/
C++17 inline
variables
In C++17 if you also mark the static member as inline
, then I believe that you can odr-use it freely or have multiple definitions across compilation units, e.g.:
#include <iostream>
class MyClass {
public:
inline static constexpr int i = 42;
};
int main() {
const int &cs = MyClass::i;
std::cout << cs << std::endl;
std::cout << &MyClass::i << std::endl;
}
More info at: How do inline variables work?