| Issue |
182030
|
| Summary |
[Clang] static constexpr member of its own class type is rejected in C++17
|
| Labels |
clang
|
| Assignees |
|
| Reporter |
ZhangYK-aha
|
For the following code:
```cpp
struct A
{
int a;
static constexpr A s{0};
};
```
I named it `test.cpp` and ran the following command locally, which produced an unexpected result:
```bash
~ $ clang++ --version
clang version 21.1.8
Target: aarch64-unknown-linux-android24
Thread model: posix
InstalledDir: /data/data/com.termux/files/usr/bin
~ $ clang++ test.cpp -std=c++17 -fsyntax-only
test.cpp:4:21: error: constexpr variable cannot have non-literal type 'const A'
4 | static constexpr A s{0};
| ^
test.cpp:4:21: note: incomplete type 'const A' is not a literal type
test.cpp:1:8: note: definition of 'A' is not complete until the closing '}'
1 | struct A
| ^
1 error generated.
```
However, according to the C++17 standard and subsequent defect reports, this code should be allowed. The reasons are as follows:
### 1. constexpr static data members are implicitly inline variables
C++17 [dcl.constexpr]/1 states:
> A function or static data member declared with the constexpr specifier is implicitly an inline function or variable ([dcl.inline]).
Therefore, the declaration of `s` here is a definition; no out-of-class definition is required. The rules for inline variable definitions ([dcl.inline]) do not mandate that the type must be complete at the point of definition.
### 2. Aggregate initialization does not require the type to be complete
The initializer `{0}` is an aggregate initialization. The semantics of aggregate initialization directly initialize members, do not call constructors, and do not require the aggregate type itself to be complete at the point of initialization (as long as the initializer itself is valid). Here, an `int` member can be initialized with 0, which does not depend on A being complete.
### 3. C++20 standard library adopts the same pattern
Class `std::strong_ordering` in the standard library of C++20 and later standards explicitly contains static constexpr members of its own type (e.g., `std::strong_ordering::less`, etc.). This proves that the standard implementation recognizes this usage and does not trigger any diagnostics.
Based on the above, Clang's current rejection of this code does not align with the standard and the resolution of the defect report, and should be considered an implementation bug.
## Expected behavior:
The code should compile successfully under -std=c++17 and later standards.
Of course, if my understanding of the standard is wrong, please forgive me.
I am not very good at English, so I described it with AI and let AI translate it into English. If there is something inappropriate, please forgive me.
I am sorry that I cannot provide more information because I am a student and I can only run the examples in my Termux on my smart phone.
_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs