[cfe-dev] extern array as non-type template argument with clang c++1z ?

Shuo Chen via cfe-dev cfe-dev at lists.llvm.org
Mon Aug 28 14:36:19 PDT 2017


Dear clang folks,

Does C++17 allow using extern array as non-type template argument?

Clang gives error when compiling follow code: https://godbolt.org/g/66vRKR

template <const char* T>
struct X {
};

extern const char tag[];
typedef X<tag> Y;

When compiling with clang from trunk @311886:

$ clang++ nontype.cc -std=c++1z
nontype.cc:6:11: error: non-type template argument refers to subobject '&tag'
typedef X<tag> Y;
          ^
1 error generated.

I found a similar question on SO: https://stackoverflow.com/questions/38147062

I traced the code a little bit, the error was emitted by
Sema::CheckTemplateArgument() at
https://github.com/llvm-mirror/clang/blob/0a0eebabaad89213cd79fe9947fbb449484b6efd/lib/Sema/SemaTemplate.cpp#L6054
Where we have Value.hasLValuePath() == false for extern array.

The code works fine in C++98/11/14 mode with clang, as well as
-std=c++17 with g++.

I also tried using a non-extern array:

const char tag[] = "abc";
struct Z {
  X<tag> x_;
};

But g++ (6/7) complains with "warning: 'Z' has a field 'Z::x_' whose
type uses the anonymous namespace [-Wsubobject-linkage]"

See https://gist.github.com/chenshuo/ed35a5615d6696be4b65a74515d598e2,
this warning only appears when array 'tag' is in defined in header
file. So I could not post a link to online compiler here.

Finally, I tried extern array with initialization:

extern const char tag[] = "abc";

Both clang and g++ compile fine, but I got linker error of duplicated
symbol: multiple definition of `tag'.

What is the correct way of using array as non-type template argument
in C++17?  Thanks in advance!

Best Regards,
Shuo Chen
http://github.com/chenshuo


More information about the cfe-dev mailing list