5

We have this kind of code:

template <typename T>
struct A {
    static constexpr A a = A{};
};


template <typename T>
struct B {
    T a;
};

B<A<int>> b;

GCC 13 seems happy with L.3 but not clang 16.

<source>:3:21: error: constexpr variable cannot have non-literal type 'const A<int>'
        static constexpr A a = A{};
                           ^
<source>:9:4: note: in instantiation of template class 'A<int>' requested here
        T a;
          ^
<source>:12:11: note: in instantiation of template class 'B<A<int>>' requested here
B<A<int>> b;
          ^
<source>:3:21: note: incomplete type 'const A<int>' is not a literal type
        static constexpr A a = A{};
                           ^
<source>:2:8: note: definition of 'A<int>' is not complete until the closing '}'
struct A {
       ^
1 error generated.
Compiler returned: 1

https://godbolt.org/z/brYMf9har

Which compiler is correct?

Nicolas
  • 598
  • 3
  • 15
  • 2
    Are you looking for "who is correct" answer specifically (in that case `language-lawyer` tag is warranted) or for something else, e.g. how to satisfy both compilers? – yeputons Jul 27 '23 at 09:30
  • 2
    I'm looking for "who is correct". We do not use clang for now, but CLion detects it as an error, as its inspections are based on clang. – Nicolas Jul 27 '23 at 09:37
  • 1
    I believe [this answer](https://stackoverflow.com/a/11929560/3854570) is still valid in C++20. – Nelfeal Jul 27 '23 at 10:23
  • 1
    [See also](https://stackoverflow.com/questions/29432283/c-static-constexpr-field-with-incomplete-type) – Nelfeal Jul 27 '23 at 10:27

1 Answers1

2

Clang is correct.

An object shall not be defined with an incomplete type; [basic.def]/5. A static constexpr data member is implicitly inline, so its declaration is a definition. And since this definition occurs inside the definition of A itself, A is still incomplete in this context, unless the context is a complete-class context. The initializer of a static data member is not a complete-class context; [class.mem.general]/7.

Brian Bi
  • 111,498
  • 10
  • 176
  • 312