假设我有以下模板类,它有一个静态成员函数,它本身实例化一个静态变量(在功能上是一个静态成员变量,在第一次调用其包含例程时实例化):
template <typename T>
struct foo
{
static int& mystatic()
{
static int value;
return value;
}
};
如果我使用 foo<T>
在一些翻译单元中 T
, 编译器将 foo<T>::mystatic::value
放入哪个目标文件?如何在链接时解决这种明显的重复/冲突?
最佳答案
您是否了解您的函数 mystatic
是具有外部链接的函数?这意味着在不同翻译单元中对 mystatic
的多个定义之间存在非常相同的冲突。此外,如果没有模板,可能会出现完全相同的问题:在头文件中定义外部链接的普通 inline
函数可能会产生相同的明显多重定义冲突(并且可以在那里重现与局部静态变量的相同问题以及)。
为了解决此类冲突,所有此类符号都由编译器以某种依赖于实现的方式进行标记。通过这样做,编译器向链接器传达了这些符号可以合法地最终被多次定义的事实。例如,一种已知的实现将此类符号放入目标文件的单独部分(有时称为“COMDAT”部分)。其他实现可能会以其他方式标记此类符号。当链接器在多个目标文件中发现此类符号时,它不会报告多重定义错误,而是从每个相同的符号中选择且仅一个,并在整个程序中使用它。每个此类符号的其他拷贝都被链接器丢弃。
这种方法的一个典型结果是,您的本地静态变量 value
必须作为外部符号包含在每个目标文件中,尽管事实上它没有从看法。符号的名称通常由函数名 mystatic
和变量名 value
以及其他一些修饰组成。
换句话说,编译器将 mystatic
的定义和变量 value
放入所有使用该成员的独立对象文件中功能。链接器稍后将确保只有一个 mystatic
和一个 value
将存在于链接程序中。可能无法确定哪个原始目标文件提供了幸存的拷贝(如果这种区分甚至有意义的话)。
关于c++ - 哪个目标文件包含以下静态模板化 "member variable"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16951787/