-
Notifications
You must be signed in to change notification settings - Fork 7
Description
Full name of submitter (unless configured in github; will be published with the issue): Jakub Jelinek
Reference (section label): cpp.cond
Link to reflector thread (if any):
Issue description:
I don't see any restrictions on <=> use in #if or #elif constant-expression.
C restricts what can't appear in constant-expression and therefore in preprocessing directives:
"Constant expressions shall not contain assignment, increment, decrement, function-call, or comma
operators, except when they are contained within a subexpression that is not evaluated."
while C++ doesn't have something like that. For assignment/increment/decrement/function-call
I think because remaining identifiers have been replaced with 0 one can't really construct something
valid, for comma operator my understanding is that C vs. C++ diverge, in both C and C++
#if 1, 2 // invalid
#endif
#if (1, 2) // valid just in C++
#endif
#if 1 || (1, 2) // valid in both C99+ and C++
#endif
#if 1 ? 1, 2 : 3 // valid in C++
#endif
#if 0 ? 1, 2 : 3 // valid in both C99+ and C++
#endif
Now,
#include <compare>
constexpr int a = (0 <=> 1) < 0;
is valid in C++20 and later while without #include it is not, and the initializer doesn't contain any identifiers.
So, the question is if
#include <compare>
#if (0 <=> 1) < 0
#endif
is supposed to be valid or not, and whether anything changes if #include is omitted. Having the preprocessor need to parse std::strong_ordering and related stuff would be a layering violation, so either it needs to have some builtin understanding on how std::strong_ordering etc. work, or it should be just disallowed. All compilers I've tried reject <=> in preprocessor constant-expression.
Suggested resolution: