C++ Linker Error With Class static constexpr

Solution 1:

I don't think this is a bug. If you change the constexpr to const, it still fails, with the exact same error.

You've declared S::X, but not defined it anywhere, so there's no storage for it. If you do anything with it that needs to know the address of it then you'll need to define it somewhere also.

Examples:

int main() {
      int i = S::X; // fine
      foo<S::X>(); // fine
      const int *p = &S::X; // needs definition
      return std::min(S::X, 0); // needs it also
}

The reason for this is that constexpr can be evaluated at compile time, but it's not required to be evaluated as such, and can equally happen at runtime. It doesn't instruct "the compiler to always treat the symbol as an expression", it hints that it would be sensible and permissible to do so if the compiler felt like it.

Solution 2:

This has been fixed in C++17.

https://en.cppreference.com/w/cpp/language/static:

If a static data member is declared constexpr, it is implicitly inline and does not need to be redeclared at namespace scope. This redeclaration without an initializer (formerly required as shown above) is still permitted, but is deprecated.