[cfe-dev] clang 4.0.0, const(expr) static class member and linker error with C++1z

Jonathan 'Rynn' Sauer via cfe-dev cfe-dev at lists.llvm.org
Tue Apr 25 05:56:29 PDT 2017


Hello,

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 §9.2.3.2p5). 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,
Jonathan


More information about the cfe-dev mailing list