在模板中存储静态变量

时间:2015-02-07 19:51:04

标签: c++ templates static

也许已经多次询问过,但我找不到一个专注于模板化函数内静态变量存储的问题。我想知道模板化函数中的静态存储位置以及编译器对它们的准确性如何? 我将提供一些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

我的静电在哪里?我是否将其初始化为在模板化函数中声明的任何静态值并不是在.BSS中似乎也不是.DSS ...即使我实例化具有不同类型的该模板函数的另一个实例,例如{{1}什么都不会改变。编译器是如何做到的?它将把这些静力学放在哪里?这些静力学将如何与模板中的静态行为完全相同 - 这意味着它们为每个实例化的模板函数保留它们的值?

1 个答案:

答案 0 :(得分:4)

可能因为没有使用变量而对变量进行了优化。您可以尝试编译到程序集(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: