模板中静态变量的存储

Storage of static variables inside templates

本文关键字:存储 变量 静态      更新时间:2023-10-16

也许这个问题已经问过好几次了,但我找不到一个问题是关于模板函数中的静态vars存储的。我想知道模板函数中的静态信息存储在哪里,编译器到底是如何处理它们的?我将提供一些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中。到目前为止还不错,所以我转向我有问题的部分,并根据以下内容更改了我的_func:

template <typename T> void my_func() {
    static T x;
}
int main() {
    my_func<int>();
    return 0;
}

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

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

我的静电去哪儿了?无论我是否将其初始化为模板函数中声明的任何值static,似乎都不适用于.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: