You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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++
#if1, 2// invalid#endif#if (1, 2) // valid just in C++#endif#if1|| (1, 2) // valid in both C99+ and C++#endif#if1 ? 1, 2 : 3// valid in C++#endif#if0 ? 1, 2 : 3// valid in both C99+ and C++#endif
Now,
#include<compare>
constexpr inta= (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.
I've amended CWG1436 to mention <=> specifically. Given that <=> returns values of C++ library types, we should assume that <=> is forbidden in the preprocessor; there is a wording gap in the standard.
Activity
t3nsor commentedon Jul 31, 2025
That's CWG1436
jensmaurer commentedon Aug 9, 2025
I've amended CWG1436 to mention
<=>specifically. Given that<=>returns values of C++ library types, we should assume that<=>is forbidden in the preprocessor; there is a wording gap in the standard.[-][cpp.cond] <=> in #if/#elif[/-][+]CWG1436 [cpp.cond] <=> in #if/#elif[/+]