I'm playing with the new template variables feature from C++14 in order to get used to it (maybe is soon to do this 'cause it seems that some compilers didn't implement it completely).
Now I'm wondering where lies each instance of a template variable. In the tests I did so far they seem to be initialized before any static data so I'm wondering if they're placed in the data segment of the program. Let's see what I've tryed so far, I have a class which prints information on construction and destruction:
struct squealer
{
squealer(std::string a_name) : m_name(a_name) { std::cout << this << ' ' << m_name << ' ' << __PRETTY_FUNCTION__ << '\n'; }
~squealer() { std::cout << this << ' ' << m_name << ' ' << __PRETTY_FUNCTION__ << '\n'; }
void f() {}
const std::string m_name;
};
And a program which instances some squealer
s in local storage, static storage and as template variables, this is the program:
// static storage squealer
squealer s("\"static\"");
// template variable squealer
template <int i> squealer test(std::string(i, 'A'));
// function using a template variable squealer
void f() { test<1>.f(); }
int main(int argc, char **argv)
{
// local storage squealer
squealer ss("local");
// using another template variable squealers
test<2>.f();
switch (argc)
{
case 1: test<3>.f(); break;
case 2: test<4>.f(); break;
case 3: test<5>.f(); break;
case 4: test<6>.f(); break;
}
return 0;
}
Here is the program and this is the output:
A squealer::squealer(std::string)
AA squealer::squealer(std::string)
AAA squealer::squealer(std::string)
AAAA squealer::squealer(std::string)
AAAAA squealer::squealer(std::string)
AAAAAA squealer::squealer(std::string)
"static" squealer::squealer(std::string)
local squealer::squealer(std::string)
local squealer::~squealer()
"static" squealer::~squealer()
AAAAAA squealer::~squealer()
AAAAA squealer::~squealer()
AAAA squealer::~squealer()
AAA squealer::~squealer()
AA squealer::~squealer()
A squealer::~squealer()
As we can see, all the template variables squealer
instances are created before the one named "static"
and at the end (as expected) the one named local
is created, the destruction order is the opposite (as expected too), so: the order of creation/initialization of template variables instances is the same of its appearance on the code regardless of the locality of this appearance and regardless of they're used or not (the f()
function is never called).
So the first question is, are this template variables placed on the data segment? I don't know how to test or check it.
The second question is, are all of this template variables squealer
instances thread safe? I've readed on n3376 §6.7 the following sentence (emphasis mine):
An implementation is permitted to perform early initialization of other block-scope variables with static or thread storage duration under the same conditions that an implementation is permitted to statically initialize a variable with static or thread storage duration in namespace scope (3.6.2). Otherwise such a variable is initialized the first time control passes through its declaration; such a variable is considered initialized upon the completion of its initialization. If the initialization exits by throwing an exception, the initialization is not complete, so it will be tried again the next time control enters the declaration. If control enters the declaration concurrently while the variable is being initialized, the concurrent execution shall wait for completion of the initialization.
From C++11 if all of the template variable squealer
instances are in static storage they should be thread safe, isn't it?
Thanks.