clang 4.0.0, const(expr) static class member and linker error with C++1z

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
Report Content as Inappropriate

clang 4.0.0, const(expr) static class member and linker error with C++1z

Martin J. O'Riordan via cfe-dev

I am trying out C++1z with clang 4.0.0 and stumbled upon the following problem. Take the following three files in the same directory:

The common header ab.hpp defines a struct "V" with a const static member "DEFAULT":

struct V {
  int i;
  constexpr V() : i(42) {}
  static const V DEFAULT;

Implementation file a.cpp defines "V::DEFAULT", using "constexpr" to enforce initialization at compile-time:

#include "ab.hpp"

constexpr V V::DEFAULT = {};

and finally implementation file b.cpp uses "V::DEFAULT":

#include "ab.hpp"

int main()
  return V::DEFAULT.i;

When compiling with C++14, this compiles and links successfully. When compiling with C++1z however I get a link error ("-mlinker-version=261" is needed because of an old "ld"):

  $ clang++ -std=c++1z -mlinker-version=261 a.cpp b.cpp
  Undefined symbols for architecture x86_64:
    "V::DEFAULT", referenced from:
       _main in a-017b90.o
  ld: symbol(s) not found for architecture x86_64

If I understand correctly, since "struct V" has external linkage (N4640 §3.5p4), the member "DEFAULT" should have external linkage as well (N4640 § However it doesn't have appear to have external linkage since it is not found by another translation unit.

Changing the definition of "V::DEFAULT" from "constexpr" to "const" makes the code link even with C++1z. However I think that a "constexpr" definition should not change the linkage of an existing declaration.

Am I completely off-base here? Or should this code compile not only with C++14, but also C++1z?

With many thanks in advance,
cfe-dev mailing list
[hidden email]