加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – 模板变量是否允许在多个翻译单元中并有效合并?

发布时间:2020-12-16 07:23:59 所属栏目:百科 来源:网络整理
导读:请参阅以下内容: https://en.cppreference.com/w/cpp/language/definition#One_Definition_Rule http://eel.is/c++draft/basic.def.odr#12 它声明允许类模板的多个定义,类模板的静态数据成员,部分模板特化等,并将作为单个定义.太棒了…但它没有提到变量模板
请参阅以下内容:

https://en.cppreference.com/w/cpp/language/definition#One_Definition_Rule

http://eel.is/c++draft/basic.def.odr#12

它声明允许类模板的多个定义,类模板的静态数据成员,部分模板特化等,并将作为单个定义.太棒了…但它没有提到变量模板吗?

如果我在多个翻译单元中有以下内容:

template<typename T>
T my_data{};

inline void test() {
    my_data<int> = 1;
}

是否会为每个翻译单元提供他们自己的my_data定义,从而产生多个符号,或者它们是否会有效地合并到程序中的单个定义中,其中一个翻译单元中的调用test()将修改另一个翻译单元的变量?

标准中的哪个部分提到了这种行为?

解决方法

根据c 14标准 [basic.def]/4:

Every program shall contain exactly one definition of every non-inline function or variable that is odr-used in that program outside of a discarded statement; no diagnostic required.

因此,如果my_data< T>如果在多个翻译单元中使用相同的模板参数,则应该有一个odr违规(没有任何诊断).内联变量出现在c 17中以解决该问题,这就是为什么type_traits * _v系列变量模板被内联声明的原因.

在实践中,使用Gcc和Clang(至少,我不能检查其他编译器),你不会得到任何odr违规,因为模板变量具有“模糊的链接”(就好像它们被声明为内联).

你可以用nm检查它.如果你运行这个命令行g -c test.cpp -std = c 14&& nm test.o | c filt | grep my_data,你应该看到my_data< int>是根据nm文档的类别的符号:

The symbol is a unique global symbol. This is a GNU extension to the standard set of ELF symbol bindings. For such a symbol the dynamic linker will make sure that in the entire process there is just one symbol with this name and type in use.

在Core issue #1849年,人们可以阅读这个不起眼的句子:

The description in 6.2 [basic.def.odr] paragraph 6 of when entities can be multiply-declared in a program does not,but should,discuss variable templates.

我敢打赌,如果所有编译器都给变量模板一个模糊的联系,那么标准的未来修订可能会反映出来.但是现在我们应该使用内联说明符,因为它在stl中完成.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读