【问题标题】:Storage of static variables inside templates在模板中存储静态变量
【发布时间】:2015-02-07 19:51:03
【问题描述】:

也许这个问题已经被问过好几次了,但我找不到一个关注模板化函数内的静态变量存储的问题。我想知道模板化函数中的静态存储在哪里以及编译器究竟是如何处理它们的? 我将提供一些 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&lt;float&gt;() 什么都不会发生改变。编译器是怎么做的?它将把这些静态变量放在哪里?这些静态变量的行为将如何与它们不在模板中的行为完全相同——这意味着它们为每个实例化的模板函数保留它们的值?

【问题讨论】:

  • 为什么要关心它的存储位置?无论如何,这个问题的 98% 是特定于编译器、平台和处理器的。那你用什么?
  • 真的不能说我为什么在乎。我只是想知道,标准是否对此或一般情况有所说明。但是,如果您阅读我的帖子,您已经知道我的编译器并且平台是 fedora-21 (linux),而 cpu 是核心 i7-4700MQ。
  • 模板是特殊的,允许它们在标头中定义并且不违反 ODR 规则。也许那里有什么东西。只是在黑暗中扔飞镖......
  • 标准不保证任何关于存储的内容,也没有节的概念——这是实现细节。标准只是说你的程序应该按照指定的方式运行,它的实现方式取决于实现。
  • 标准对这一切只字未提。这些是实现细节,与您的程序的语义没有关系。

标签: c++ templates static


【解决方案1】:

可能因为未使用该变量而被优化掉了。您可以尝试编译为程序集(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:

【讨论】:

  • 是的,你是对的,编译器优化了变量。实际上,该变量位于 .bss 段中。
猜你喜欢
  • 1970-01-01
  • 2010-12-05
  • 2019-05-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多