Wrath
Wrath

Reputation: 683

Storage of static variables inside templates

Maybe this has been asked several times but I couldn't find a single question that were focused on static vars storage inside templated functions. I would like to know where statics within templated functions are stored and how what is the compiler doing with them exactly? I'm going to provide some g++ memory layout just to show why I don't get them. My first code I cheched was rather simple:

#include <iostream>
using namespace std;

void my_func() {
    static int x;
}

int main() {
    my_func();

    return 0;
}

When I check the memory layout of this program with g++ 4.8.1 I end up with the following sections:

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

Nothing unexpected so far. The uninitialized static variable is stored within the .bss segment. The same goes if I initialize the x variable to 0, while if I initialize it with any non-zero value the; still nothing unexpected:

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

x in this case is stored within the data segment instead of bss. So far so good, so I turned towards my questionable part and changed my_func according to the following:

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

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

Now this was interesting to me but the memory layout became:

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

Where did my static go? Whether I initialize it to any value static declared within templated functions doesn't seem to apprear nor in .DS neither in .BSS... Even if I instantiate another instance of that template function with different type for example my_func<float>() nothing is going to change. How is the compiler doing it? Where will it put those statics and how will these statics behave exactly the same as they weren't in templates - meaning they keep their values for each instantiated template function?

Upvotes: 1

Views: 248

Answers (1)

Adam Sosnowski
Adam Sosnowski

Reputation: 1284

Probably the variable is being optimized away because it is not used. You may try to compile to assembly (gcc -S) and then lookup the variable in the output.

This experiment seems to confirm it:

> 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:

Upvotes: 4

Related Questions