gpt4 book ai didi

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

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:14:20 24 4
gpt4 key购买 nike

请参阅以下内容:

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-violation(没有任何诊断)。 inline变量出现在 c++17 中以解决该问题,这就是为什么 type_traits *_v 系列变量模板已声明 inline .

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

您可以使用 nm 查看它.如果运行此命令行 g++ -c test.cpp -std=c++14 && nm test.o | c++filt | grep my_data , 你应该看到 my_data<int>是类别的符号u这是根据 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.

我敢打赌,如果所有编译器都给变量模板一个模糊的链接,那么 future 的标准修订版可能会反射(reflect)出这一点。但是现在我们应该像在 STL 中那样使用内联说明符。

关于c++ - 多个翻译单元中是否允许模板变量并有效合并?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52630051/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com