This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 119b. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.

2026-02-22


2947. Limiting macro expansion in pp-module

Section: 15.5  [cpp.module]     Status: review     Submitter: Jason Merrill     Date: 2024-10-29

Consider:

  #define DOT_BAR .bar
  export module foo DOT_BAR;

The current rules appear to make this valid, referring to module foo.bar in phase 7. This ought to be ill-formed to align with the goal of keeping module directives parsable by simple tools.

Proposed resolution (2026-02-22):

  1. Change in 15.5 [cpp.module] paragraph 1 as follows:

      pp-module:
          exportopt module pp-tokensopt ; new-line
    
    The pp-tokens, if any, of a pp-module shall be of the form:
       pp-module-name pp-module-partitionopt pp-tokensopt
    
    where the pp-tokens (if any) shall not begin with a ( preprocessing token and the grammar non-terminals are defined as: ...

    No identifier in the pp-module-name or pp-module-partition shall currently be defined as an object-like macro or followed by ( as the next preprocessing token at the start of phase 4 of translation (5.2 [lex.phases]).

  2. Delete 15.5 [cpp.module] paragraph 2 as follows:

    Any preprocessing tokens after the module preprocessing token in the module directive are processed just as in normal text. [Note 1: Each identifier currently defined as a macro name is replaced by its replacement list of preprocessing tokens. —end note]
  3. Change in 15.5 [cpp.module] paragraph 3 as follows:

    The module and export (if it exists) preprocessing tokens are replaced by the module-keyword and export-keyword preprocessing tokens respectively. [Note: This makes the line no longer a directive so it is not removed at the end of phase 4. —end note] After this replacement, the preprocessing tokens that constituted the directive are a text-line and are processed as normal text. [Note: No macro expansion is possible for the pp-module-name and pp-module-partition. -- end note] Processing the remainder of the input shall produce a ; or [ preprocessing token following the pp-module-name and optional pp-module-partition.
  4. Add 15.5 [cpp.module] paragraph 4 with examples:

    [ Example:
      #define DOT_BAR .bar
      export module foo DOT_BAR;   // error: expansion of DOT_BAR; does not begin with ; or [
    

    -- end example ]

    [ Example:

      #define MOD_ATTR [[vendor::shiny_module]]
      export module M MOD_ATTR ;        // OK
    

    -- end example ]

    [ Example:

      export module a
      .b;                         // error: preprocessing token after pp-module-name is not ; or [
    

    -- end example ]

    [ Example:

      export module M [[
      attr1,
      attr2 ]] ;                 // OK
    

    -- end example ]

    [ Example:

      export module M
      [[ attr1,
      attr2 ]] ;                 // OK
    

    -- end example ]

    [ Example:

      export module M; int
      n;                         // OK
    

    -- end example ]