Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Status of inconsistent template specializations across translation units?

Please consider the below program:

FILE A.H

template <typename T> struct C { static constexpr int x = 42; };

FILE B.H

#include "A.H"

template <> struct C<int> { static constexpr int x = 43; };

FILE A.CC

#include "A.H"

void a() { std::cout << C<int>::x; }

FILE B.CC

#include "B.H"

void b() { std::cout << C<int>::x; }

FILE MAIN.CC

void a(); void b();

int main() { a(); b(); }

What is the status of this program? Is it ill-formed, ill-formed with no diagnostic required, does it exhibit undefined behaviour, or none of the above (its okay)?

If none of the above, what is the output of the program?

If one of the above, what rule does it violate?

(Also, would the answer be different if B.H contained a partial specialization rather than an explicit specialization?)

like image 330
Andrew Tomazos Avatar asked Mar 03 '23 16:03

Andrew Tomazos


1 Answers

This is [temp.arg.template]/2:

If a specialization is not visible at the point of instantiation, and it would have been selected had it been visible, the program is ill-formed, no diagnostic required.

The specialization for C<int> isn't visible in the definition of a(), but would've been selected if it had been.


But more importantly, this is the limerick (spacing mine):

When writing a specialization,
be careful about its location;
or to make it compile
will be such a trial
as to kindle its self-immolation.

like image 53
Barry Avatar answered Apr 06 '23 01:04

Barry