Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

If I have: a.hpp a.cpp and main.cpp includes a.hpp, and in a.hpp I write

template<typename T>
constexpr int num;
template<>
constexpr int num<float> = 1;
template<>
constexpr int num<double> = 2;

Do I risk defining the variable num multiple times both in a.o and main.o? Or is it declared inline? Shall I put template variables specializations inside a.cpp? What changes if I wrap a.hpp into a namespace?


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
547 views
Welcome To Ask or Share your Answers For Others

1 Answer

Do I risk defining the variable num multiple times both in a.o and main.o?

You do. For non-template variables, constexpr implies const and const at the namespace level implies internal linkage, but not for variable templates. It seems that this is underspecified in the standard. The current draft has the following

Note 1: An instantiated variable template that has const-qualified type can have external or module linkage, even if not declared extern.

Experimentally, different compilers give them different linkages. For example, with GCC 9.3.0 and 10.2.0 num<float> has internal linkage:

nm -C a.o
...
0000000000000004 r num<float>

but with Clang 10.0.0 it has external linkage:

nm -C a.o
...
0000000000000000 R num<float>

As a result, if you try to include a.hpp in two compilation units, you'll get a link error with Clang.


Or is it declared inline?

No, explicit inline is needed.

What changes if I wrap a.hpp into a namespace?

I guess you're talking about an unnamed namespace. In this case each compilation unit is guaranteed to get its own (private) copy.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...