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

2024-11-11


2893. Instantiations in discarded if constexpr substatements

Section: 13.9.2  [temp.inst]     Status: NAD     Submitter: Jan Schultke     Date: 2024-05-09

(From submission #535.)

Consider:

  void g() {
    auto f = [](auto s) {
      s.x = 0;
    };
    if constexpr (false) {
      f(0);   // well-formed?
    }
  }

Note that the lambda has a deduced return type, yet per the current wording, f is not instantiated here.

Possible resolution:

Add a new paragraph before 13.9.2 [temp.inst] paragraph 9 as follows:

The existence of a definition of a function is considered to affect the semantics of the program if the function is named by an expression (6.3 [basic.def.odr]) and the function's declared return type is a placeholder type (9.2.9.7 [dcl.spec.auto]). [ Example:

  void g() {
    auto f = [](auto s) {
      s.x = 0;  // #1
    };
    if constexpr (false) {
      f(0);     // error at #1: type int has no member named x
    }
  }

-- end example ]

If the function selected by overload resolution (12.2 [over.match]) can be determined without ...

CWG 2024-06-14

The original example involving a deduced return type of the lambda is ill-formed, because the semantics of the program are affected by its return type, and thus an instantion is required (13.9.2 [temp.inst] paragraph 5): If the lambda returned a class type with a private destructor, the program would be ill-formed.

The modified example with a void return type of the lambda is well-formed; clang's implementation divergence is believed to be a bug.

As a side note, odr-use is not affected by discarded statements; just some of the effects of odr-use do not materialize (6.3 [basic.def.odr] paragraph 12).