c++ - Why is this circular template instantiation legal? -


i don't understand compiler's doing here:

#include <iostream> using namespace std;  // non-default-constructable struct struct x {     x(int v) : x(v) {}     const int x; };  template< typename t> struct {     static const x a; };  // trigger compiler error if try instantiate default template template< typename t > const x a<t>::a;   template<> struct a<int> {     static const x a; };  template<> struct a<float> {     static const x a; };  // not infinitely circular? const x a<int>::a = x(a<float>::a.x + 1); const x a<float>::a = x(a<int>::a.x + 1);  int main() {     // error expected, a<bool>::a cannot default-constructed     // cout << a<bool>::a.x << endl;       // compiles , prints "1 2"     cout << a<int>::a.x << " " << a<float>::a.x << endl;     return 0; } 

i have expected 2 specialized definitions of a generate compiler error, since both initialized using value of other, , there isn't default constructor fall on. apparently, compiles in ideone , prints 1 2. how did compiler arrive conclusion 2 instances of x should initialized these values?

that happens side effect of initialization of non-local variables. standard says:

3.6.2 initialization of non-local variables [basic.start.init]

...
... variables static storage duration (3.7.1) or thread storage duration (3.7.2) shall zero-initialized (8.5) before other initialization takes place...
... static initialization shall performed before dynamic initialization takes place. dynamic initialization of non-local variable static storage duration unordered if variable implicitly or explicitly instantiated specialization, , otherwise ordered [ note: explicitly specialized static data member or variable template specialization has ordered initialization. —end note ] variables ordered initialization defined within single translation unit shall initialized in order of definitions in translation unit.

that's happens here:

  • a<int>::a , a<float>::a both 0 initialized
  • they initialized in order of definitions
    • first a<int>::a reads lies in a<float>::a 0 because of previous 0 initialization, adds 1 , initialized 1
    • then a<float>::a gets value of initialized a<int>::a 1, adds 1 , initialized 2

that means formed program.

but same paragraph says later:

if initialization of object obj1 refers object obj2 of namespace scope potentially requiring dynamic initialization , defined later in same translation unit, unspecified whether value of obj2 used value of initialized obj2 (because obj2 statically initialized) or value of obj2 merely zero-initialized

so unsure whether output required 1 2, or whether 2, 1 if dynamic initialization of a<int>::a first triggers dynamic initialization of a<float>::a


Comments

Popular posts from this blog

Command prompt result in label. Python 2.7 -

javascript - How do I use URL parameters to change link href on page? -

amazon web services - AWS Route53 Trying To Get Site To Resolve To www -