Skip to content

[lex] Reserved preprocessing-tokens *can* be conditionally used in the program #8692

@TymianekPL

Description

@TymianekPL

In addition, some identifiers appearing as a token or preprocessing-token are reserved for use by C++ implementations and shall not be used otherwise; no diagnostic is required.

[lex.name]/3

  1. The source file is decomposed into preprocessing tokens ([lex.pptoken]) and sequences of whitespace characters (including comments). A source file shall not end in a partial preprocessing token or in a partial comment.9 Each comment ([lex.comment]) is replaced by one U+0020 space character. New-line characters are retained. Whether each nonempty sequence of whitespace characters other than new-line is retained or replaced by one U+0020 space character is unspecified. As characters from the source file are consumed to form the next preprocessing token (i.e., not being consumed as part of a comment or other forms of whitespace), except when matching a c-char-sequence, s-char-sequence, r-char-sequence, h-char-sequence, or q-char-sequence, universal-character-names are recognized ([lex.universal.char]) and replaced by the designated element of the translation character set ([lex.charset]). The process of dividing a source file's characters into preprocessing tokens is context-dependent.
    [Example 1: See the handling of < within a #include preprocessing directive ([lex.header], [cpp.include]). — end example]
  2. The source file is analyzed as a preprocessing-file ([cpp.pre]). Preprocessing directives ([cpp]) are executed, macro invocations are expanded ([cpp.replace]), and _Pragma unary operator expressions are executed ([cpp.pragma.op]). A #include preprocessing directive ([cpp.include]) causes the named header or source file to be processed from phase 1 through phase 4, recursively. All preprocessing directives are then deleted. Whitespace characters separating preprocessing tokens are no longer significant.

[lex.phases]/3,4

Each and every preprocessing-token is used in the translation before the 4th translation phase which executes preprocessing directives such as #ifdef.

Why is this a defect? You cannot use and query names like __cplusplus or feature-test macros, since these are preprocessing-tokens (not tokens) reserved for use by C++ implementations, and therefore shall not be used within a program. With such definition, this program is ill-formed (no diagnostics required):

#include <print>

int main()
{
     #if __cplusplus >= 202302L
     std::print("Hello C++23 and beyond!");
     #endif
}

I don't think this is the desired behaviour.

Metadata

Metadata

Assignees

No one assigned

    Labels

    not-editorialIssue is not deemed editorial; the editorial issue is kept open for tracking.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions