Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does the one-definition-rule force a single static function variable to be created?

As an example, consider this header:

#include <iostream>

template<bool = true>
struct A {
    A() {
        static int x;
        std::cout << &x << "\n";
    }
};

static A<> a;

What if I had two different C++ files including this file - would it print the same address twice, guaranteed? Even more importantly, if x was an object of a different type with a non-trivial constructor, would it be guaranteed to only be run once?

like image 314
orlp Avatar asked Dec 10 '13 02:12

orlp


1 Answers

The standard [C++11 14.8/2] says

Each function template specialization instantiated from a template has its own copy of any static variable.

I assume (and sincerely hope) that member functions of a template class are treated the same way, although I can't find the specific language that says so.

In any case, apart from the usual risks associated with initialising static variables in a multithreaded context, I'm sure this would be fine. A<true>::A() (and the internal "static int A<true>::A::x") would be marked as weak symbols and one version would be picked at link time, the same as any other template. (Obviously, an instantiation of A<false> would be distinct from A<true>.)

Edit for comment:

The worry about different translation units seems to be covered by section [3.2/5], defining the ODR:

If D is a template and is defined in more than one translation unit, then... [providing the definitions are identical]... the program shall behave as if there were a single definition of D.

The actual requirements are a bit more language-lawyery (dependent names at the point of instantiation must be the same, etc etc), but I think this is the bit that puts you in the clear :-)

like image 100
Tristan Brindle Avatar answered Oct 03 '22 10:10

Tristan Brindle