全局变量和 constexpr(是否内联?)
Global variables and constexpr (inline or not?)
如果我有:a.hpp a.cpp 和 main.cpp 包括 a.hpp,并且在 a.hpp 我写
template<typename T>
constexpr int num;
template<>
constexpr int num<float> = 1;
template<>
constexpr int num<double> = 2;
我是否冒着在 a.o 和 main.o 中多次定义变量 num 的风险?还是声明为内联?我应该将模板变量特化放在 a.cpp 中吗?如果我将 a.hpp 包装到命名空间中会发生什么变化?
Do I risk defining the variable num
multiple times both in a.o and main.o?
是的。对于非模板变量,constexpr
意味着 const
并且 const
在名称空间级别意味着内部 linkage,但不适用于变量模板。似乎这在标准中没有明确规定。目前的草案有以下内容
Note 1: An instantiated variable template that has const
-qualified type can have external or module linkage, even if not declared extern
.
根据实验,不同的编译器赋予它们不同的 linkage。例如,GCC 9.3.0 和 10.2.0 num<float>
有内部 linkage:
nm -C a.o
...
0000000000000004 r num<float>
但对于 Clang 10.0.0,它具有外部 linkage:
nm -C a.o
...
0000000000000000 R num<float>
因此,如果您尝试在两个编译单元中包含 a.hpp
,Clang 会出现 link 错误。
Or is it declared inline?
否,需要显式 inline
。
What changes if I wrap a.hpp into a namespace?
我猜你说的是未命名的命名空间。在这种情况下,保证每个编译单元都有自己的(私有)副本。
如果我有:a.hpp a.cpp 和 main.cpp 包括 a.hpp,并且在 a.hpp 我写
template<typename T>
constexpr int num;
template<>
constexpr int num<float> = 1;
template<>
constexpr int num<double> = 2;
我是否冒着在 a.o 和 main.o 中多次定义变量 num 的风险?还是声明为内联?我应该将模板变量特化放在 a.cpp 中吗?如果我将 a.hpp 包装到命名空间中会发生什么变化?
Do I risk defining the variable
num
multiple times both in a.o and main.o?
是的。对于非模板变量,constexpr
意味着 const
并且 const
在名称空间级别意味着内部 linkage,但不适用于变量模板。似乎这在标准中没有明确规定。目前的草案有以下内容
Note 1: An instantiated variable template that has
const
-qualified type can have external or module linkage, even if not declaredextern
.
根据实验,不同的编译器赋予它们不同的 linkage。例如,GCC 9.3.0 和 10.2.0 num<float>
有内部 linkage:
nm -C a.o ... 0000000000000004 r num<float>
但对于 Clang 10.0.0,它具有外部 linkage:
nm -C a.o ... 0000000000000000 R num<float>
因此,如果您尝试在两个编译单元中包含 a.hpp
,Clang 会出现 link 错误。
Or is it declared inline?
否,需要显式 inline
。
What changes if I wrap a.hpp into a namespace?
我猜你说的是未命名的命名空间。在这种情况下,保证每个编译单元都有自己的(私有)副本。