2

我从两个翻译单元中获取以下实例化变量模板的地址:

template<class T> bool b = true;
template<class T> const bool cb = true;
template<class T> inline const bool icb = true;

我正在打印和b<int>的地址。这是clang所说的:cb<int>icb<int>

0x6030c0 0x401ae4 0x401ae5  // first translation unit
0x6030c0 0x401ae4 0x401ae5  // second translation unit

所有地址都是相同的,有点预期。这是gcc 所说的:

0x6015b0 0x400ef5 0x400ef4  // first translation unit
0x6015b0 0x400ef6 0x400ef4  // second translation unit

cb<int>变更地址。嗯?这是一个错误吗?如果没有,有人可以向我解释这种影响吗?

4

2 回答 2

2

对我来说,这似乎与CWG 问题 1713有关:

变量模板特化的链接

给定一个命名空间范围声明,如

template<typename T> T var = T();

应该T<const int>凭借其 const 限定类型具有内部链接吗?还是应该继承模板的链接?

2014 年 2 月会议记录

CWG 指出,链接是按名称进行的,变量模板的特化与变量模板的名称没有分开的名称,因此特化将具有模板的链接。

Clang 似乎在跟踪它。模板名称具有外部链接,由此产生的变量也是如此。

最终,标准本身目前并没有很好地指定变量模板专业化的预期链接。它是为常规变量指定的,但模板是不同的野兽。

于 2019-10-29T14:40:21.080 回答
1

来自 C++ 标准(6.5 程序和链接)

3 具有命名空间范围 (6.3.6) 的名称如果是

(3.2) — 非 volatile const 限定类型的非内联变量,既没有显式声明 extern 也没有先前声明为具有外部链接;或者

所以变量模板的特化是cb有内在联系的。这意味着它的地址在不同的编译单元中可以不同。

于 2019-10-29T14:36:18.943 回答