-
Notifications
You must be signed in to change notification settings - Fork 15.2k
Description
This code (extracted from systemtap 5.4) builds fine with g++ 15.2, but errors out with clang++ 21.1.5:
enum a {
b
};
const a c = (a) -1;
int main(int argc, char **argv) {
int d;
switch(d) {
case c:
break;
}
}
clang's complaint is
test.cpp:10:7: error: case value is not a constant expression
10 | case c:
| ^
test.cpp:10:7: note: initializer of 'c' is not a constant expression
test.cpp:5:9: note: declared here
5 | const a c = (a) -1;
| ^
1 error generated.
Not 100% sure which compiler is doing the right thing here; the problem persists if I change const a c = (a) -1; to constexpr a c = (a) -1; (gcc still compiles it without even throwing a warning about it, even with -Wall -Wextra).
Both compilers are set up to use -std=c++20.
Making it even more obvious with constexpr a c = static_cast<a>(static_cast<unsigned>(-1)); results in another situation where gcc and clang disagree:
clang:
test.cpp:5:13: error: constexpr variable 'c' must be initialized by a constant expression
5 | constexpr a c = static_cast<a>(static_cast<unsigned>(-1));
| ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
test.cpp:5:17: note: integer value 4294967295 is outside the valid range of values [0, 1] for the enumeration type 'a'
5 | constexpr a c = static_cast<a>(static_cast<unsigned>(-1));
| ^
test.cpp:10:7: error: case value is not a constant expression
10 | case c:
| ^
test.cpp:10:7: note: initializer of 'c' is not a constant expression
test.cpp:5:13: note: declared here
5 | constexpr a c = static_cast<a>(static_cast<unsigned>(-1));
| ^
2 errors generated.
gcc still compiles it without complaining about anything.
Again not sure what the standard says about this, clang's error certainly looks reasonable in this case (but I'd think gcc is right in the constexpr a c = (a) -1; case).