Can static and dynamic template initialization be interleaved?

Viewed 118

As I understand it, given the following code:

template<int N> 
int i = i<N - 1> + i<N - 1>;  // primary variable template

template<> int i<0> = 1;      // and explicit specialization

the following program must return 2:

int main () { return i<1>; }

but this program can return 0 or 4:

int main () { return i<2>; }

since evaluating the instantiation of i<2> gives:

int i<2> = i<1> + i<1>;       // generated by the compiler

Here, since i<1> is only implicitly instantiated, the compiler can use either the statically initialized value of i<1>, which is 0, or the dynamically initialized value, which is 2.

Here's a comparison of different compilers giving different outputs (clang returns 0, gcc returns 4).

The question is - can this program return 2?

int main () { return i<2>; }

i.e. in the initialization of i<2>, can different initializations be used for the different uses of i<1>? Can the program return some other value entirely?

2 Answers

You know from Recursive computation using variable templates - gcc vs clang that the dynamic initializations of i<1> and i<2> are indeterminately sequenced. Indeterminately sequenced evaluations can't interleave (overlap):

Evaluations A and B are indeterminately sequenced when either A is sequenced before B or B is sequenced before A, but it is unspecified which. [ Note: Indeterminately sequenced evaluations cannot overlap, but either could be executed first.  — end note ]

So in the dynamic initialization of int i<2> = i<1> + i<1>;, either the static or the dynamic value of i<1> is used for both summands, depending on whether the dynamic initialization of i<1> has already happened.

the statically initialized value of i<1>, which is 0

Where do you get 0 from? You yourself said just above that statement that i<1> must be 2.

So, given:
i<0> = 1
And:
i<1> = i<0> + i<0> = 1 + 1 = 2
And:
i<2> = i<1> + i<1>
Then:
i<2> = 2 + 2 = 4

It can't be anything other than 4.

Related