Undefined reference error for static constexpr member

*爱你&永不变心* 提交于 2019-11-28 02:37:25

问题


Consider this code:

#include <vector>

struct A {
  static constexpr int kDefaultValue = -1;
  std::vector<int> v;
  A(int n): v(n, A::kDefaultValue) {}
};

int main() {
  A(10);
  return 0;
}

It fails to link (llvm clang, gcc 4.9, both on OS X):

Undefined symbols for architecture x86_64:
  "A::kDefaultValue", referenced from:
      A::(int) in main.cpp.o
ld: symbol(s) not found for architecture x86_64

The question is what's wrong with it? It can be fixed by static_cast-ing A::kDefaultValue to int. Or by moving kDefaultValue out of A. Both cases seem to be ugly. Is this another way to make it link?


回答1:


This behaviour is vexing me time and again. The cause of the trouble is that your

A(int n): v(n, A::kDefaultValue) {}

odr-uses the static constexpr member, since the constructor of v takes a constant reference second argument. Odr-usage requires a definition somewhere, i.e.

const int A::kDefaultValue;

in some compilation unit (which is compiled and linked to main()). This requirement has been dropped in C++17 and the corresponding definition (as above) deprecated.

However, a definition is not always possible (for example for members of class templates) and the simplest way to avoid both the definition and your error is

A(int n): v(n, int(A::kDefaultValue)) {}

which creates a temporary to be passed to the constructor of v (but since the latter is fully inline, the compiler may optimise that away).




回答2:


The behavior changed since C++17. Before C++17, even a constexpr static data member must be initialized inside the class definition, definition at namespace scope is still required; Since C++17 the namespace scope definition is not required again.

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. (since C++17)

Compiling your code with a compiler supporting C++17 would work fine.

LIVE demo with gcc7



来源:https://stackoverflow.com/questions/40690260/undefined-reference-error-for-static-constexpr-member

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!