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

2024-12-06


2776. Substitution failure and implementation limits

Section: 4.1.1  [intro.compliance.general]     Status: open     Submitter: Corentin Jabot     Date: 2023-07-27     Liaison: EWG

Are there behavioral bounds in case an implementation limit is encountered? For example, a constant expression may fail to be recognized as such due to an implementation limit (e.g. a recursion or step limit), causing overload resolution to pick a different overload. Is that acceptable?

Possible resolution:

  1. Change in 4.1.1 [intro.compliance.general] paragraph 2 as follows:

    Although this document states only requirements on C++ implementations, those requirements are often easier to understand if they are phrased as requirements on programs, parts of programs, or execution of programs as specified in the rules in Clause 5 [lex] through Clause 33 [thread] and Annex D. Such requirements have the following meaning:
    • If a program contains a violation of a rule for which no diagnostic is required, this document places no requirement on implementations with respect to that program.

    • Otherwise, if an implementation limit (Annex B) is reached during translation, an implementation shall reject the program.

      Recommended practice: An implementation should document limits where they are known, and should issue a diagnostic in cases where it can reasonably detect that the implementation limit is reached.

    • If a program contains no violations of the rules in Clause 5 [lex] through Clause 33 [thread] and Annex D, a conforming implementation shall, within its resource limits as described in Annex B, accept and correctly execute [ Footnote: ... ] that program.
    • If a program contains a violation of a rule for which no diagnostic is required, this document places no requirement on implementations with respect to that program.
    • Otherwise, if a that program contains a violation of any diagnosable rule or an occurrence of a construct described in this document as “conditionally-supported” when the implementation does not support that construct, a conforming implementation shall issue at least one diagnostic message.
    • Otherwise, a conforming implementation shall accept and correctly execute that program. [ Note: "Correct execution" can include undefined behavior, depending on the data being processed; see Clause 3 [intro.defs] and 4.1.2 [intro.abstract]. -- end note ]
  2. Add a new paragraph after 4.1.2 [intro.abstract] paragraph 6 as follows:

    [Note 2 : More stringent correspondences between abstract and actual semantics can be defined by each implementation. -- end note]

    If an implementation limit (Annex B) is reached, the behavior is undefined.

    Recommended practice: An implementation should document limits where they are known and abort the execution of the program in cases where it can reasonably detect that the implementation limit is reached.

  3. Change in 7.7 [expr.const] paragraph 5 as follows:

    • ...
    • an expression that would exceed the implementation-defined limits (see Annex B);
    • an operation that would have undefined behavior as specified in Clause 4 [intro] through Clause 15 [cpp], excluding 9.12.3 [dcl.attr.assume] and exceeding an implementation limit (4.1.2 [intro.abstract]); [ Footnote: ... ]
      [ Example:
        constexpr bool f(int x) { return (x == 0) || f(x-1); }
        const bool g = f(60000);    // well-formed static initialization (6.9.3.2 [basic.start.static]);
                                    // program can be rejected because implementation limit is reached
      
      -- end example ]
    • ...
  4. Change in 13.9.2 [temp.inst] paragraph 16 as follows:

    There is an implementation-defined quantity that specifies the limit on the total depth of recursive instantiations (Annex B), which could involve more than one template. The result of an infinite recursion in instantiation is undefined.

CWG 2023-08-25

For the example in change 3, implementations currently switch to dynamic initialization when their implementation limits related to constant evaluation are exceeded. This might be surprising to users, because dynamic initialization can exhibit order-of-initialization issues. It might be less harmful to reject such situations as ill-formed. Furthermore, it is unclear whether implementations can reliably determine that an implementation limit is reached, before crashing.

CWG is requesting EWG guidance via paper issue #1631.

EWG 2023-11-07

EWG is soliciting a paper to make this either ill-formed, no diagnostic required, or well-formed.