Skip to content

CWG1436 [cpp.cond] <=> in #if/#elif #735

Closed

Description

@jakubjelinek

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:

Activity

  1. t3nsor commented on Jul 31, 2025

    @t3nsor

    That's CWG1436

  2. jensmaurer commented on Aug 9, 2025

    @jensmaurer
    Member

    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.

  3. changed the title [-][cpp.cond] <=> in #if/#elif[/-] [+]CWG1436 [cpp.cond] <=> in #if/#elif[/+] on Aug 9, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions