在模板中存储静态变量

Storage of static variables inside templates

也许这个问题已经被问过好几次了,但我找不到一个关注模板函数内静态变量存储的问题。我想知道模板函数中的静态变量存储在哪里,以及编译器是如何处理它们的? 我将提供一些 g++ 内存布局,只是为了说明为什么我没有得到它们。 我检查的第一个代码相当简单:

#include <iostream>
using namespace std;

void my_func() {
    static int x;
}

int main() {
    my_func();

    return 0;
}

当我用 g++ 4.8.1 检查这个程序的内存布局时,我得到以下部分:

.text: 1845
.data:  620
.bss:    12

到目前为止没有意外。未初始化的静态变量存储在 .bss 段中。如果我将 x 变量初始化为 0,同样如此,而如果我用任何非零值初始化它;仍然没有意外:

.text: 1845
.data:  624
.bss:     8

x 在这种情况下存储在数据段而不是 bss 中。到目前为止一切顺利,所以我转向我有问题的部分并根据以下内容更改 my_func:

template <typename T> void my_func() {
    static T x;
}

int main() {
    my_func<int>();
    return 0;
}

现在这对我来说很有趣,但内存布局变成了:

.text: 1845
.data:  620
.bss:     4

我的静电去哪儿了?我是否将它初始化为在模板函数中声明的任何静态值似乎都没有出现,也没有出现在.DS 中,也没有出现在.BSS 中......即使我用不同类型实例化该模板函数的另一个实例,例如 my_func<float>() 没有将会改变。编译器是怎么做到的?它将把这些静态变量放在哪里,这些静态变量的行为如何与它们不在模板中时完全相同——这意味着它们为每个实例化的模板函数保留它们的值?

可能变量被优化掉了,因为它没有被使用。您可以尝试编译为程序集 (gcc -S),然后在输出中查找变量。

这个实验似乎证实了这一点:

> cat static.cpp 
#include <iostream>

template<class T>
int func()
{
  static int x = 0x666;
  return 3;
}

int main()
{
  std::cout << func<int>();
  return 0;
}
> g++ -S static.cpp && c++filt < static.s | grep ::x 
> sed -i 's/return 3/return x/' static.cpp
> g++ -S static.cpp && c++filt < static.s | grep ::x 
        movl    int func<int>()::x(%rip), %eax
        .weak   int func<int>()::x
        .section        .data._ZZ4funcIiEivE1x,"awG",@progbits,int func<int>()::x,comdat
        .type   int func<int>()::x, @gnu_unique_object
        .size   int func<int>()::x, 4
int func<int>()::x: