Is an implementation required to diagnose ODR-violations of duplicated definitions of the same explicit specialization within the same TU?
Asked Answered
P

1

9

Consider a templated entity, say (A) a function template, and (B) a member enum of a class template.

// (A)
template<auto>
int f();

// (B)
template <auto>
struct T { enum class E; };

Is an implementation required to diagnose ODR-violations due to duplicated definitions of the same explicit specialization of such a template entity? Or, in other words, does [basic.def.odr]/1 apply for explicit specializations?


As an example GCC and Clang both diagnoses the following program as ill-formed:

// Single translation unit;
// primary template of 'f' declared as in (A) above.
template<>
int f<0>() { return 0; }

template<>
int f<0>() { return 1; }  
  // GCC & Clang - error: redefinition of 'int f() [with auto <anonymous> = 0]'

whereas only Clang diagnoses the follow program as ill-formed, whilst GCC accepts it:

// Single translation unit;
// primary template of 'T' defined as in (B) above.
template<>
enum class T<0>::E { ex };

template<>
enum class T<0>::E { ey };
  // Clang only - error: redefinition of 'E'

Ill-formed NDR, or ill-formed? (/both compilers correct, or GCC bug?)


Tested on various GCC and Clang versions, for -std=c++17 and -std=c++2a, with the same result

Pearly answered 27/11, 2020 at 17:50 Comment(0)
P
3

Is an implementation required to diagnose ODR-violations due to duplicated definitions of the same explicit specialization of such a template entity?

Yes.

Although [temp.spec]/5.2 specifies that multiple definitions of an explicit specialization in a program is ill-formed (whilst referring to [basic.def.odr]) NDR (no diagnostic required), multiple definitions within a single TU falls under [basic.def.odr]/1, as e.g. an explicit specialization of a class template (for some set template arguments) is a class.

No translation unit shall contain more than one definition of any variable, function, class type, enumeration type, or template.

A violation [basic.def.odr]/1 is not NDR and an implementation shall diagnose it, which both GCC and Clang does so for ODR-violating explicit specializations (within the same TU) of:

  • function templates, and
  • class templates, and
  • variable templates, and
  • member functions of class templates, and
  • static data members of class templates, and
  • member classes of class templates.

However, only Clang diagnoses it for TU-local ODR-violations for explicit specializations of member enumerations of class templates, which is the very example used in the question.

Thus, this non-diagnosed case for member enumerations is a GCC bug (filed as part of this question):

Pearly answered 3/12, 2020 at 13:38 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.