3

The following C++11 program produces an undefined reference to S<42>::s error in both gcc and clang...

#include <iostream>

template<int i> struct S;

template<> struct S<42> { static constexpr char s[] = "foo"; };

int main()
{
    std::cout << S<42>::s << std::endl;
}

By adding the following extra declaration (related question) to the program...

constexpr char S<42>::s[];

...it suppresses the error, and the program compiles.

Where in the standard does it specify that a program without that extra declaration is ill-formed? Which rules are in play here exactly?

Community
  • 1
  • 1
Andrew Tomazos
  • 66,139
  • 40
  • 186
  • 319

1 Answers1

3

ยง 9.4.2/3:

A static data member of literal type can be declared in the class definition with the constexpr specifier; if so, its declaration shall specify a brace-or-equal-initializer in which every initializer-clause that is an assignment-expression is a constant expression. The member shall still be defined in a namespace scope if it is odr-used (3.2) in the program and the namespace scope definition shall not contain an initializer.

[emphasis added]

It looks to me like when you print out the value in main that's an odr-use, so the compilers are right: the definition is required.

Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111