Skip to content

CWG2893 [stmt.if] Instantiations in if constexpr (false) outside templates #535

@eisenwave

Description

@eisenwave

Reference: [stmt.if] p2

Link to reflector/Mattermost: https://lists.isocpp.org/core/2024/05/15848.php, https://chat.isocpp.org/general/pl/5gki63y36fd9m8wwk77qzofica

Issue Description

int main() {
    auto f = [](auto s) {
        s.x = 0;
    };
    if constexpr (false) {
        f(0);
    }
}

This program is well-formed because neither of the conditions (see [temp.inst] p5) for instantiating the call operator template of the generic lambda are met:

  • A definition of operator()<int> is not needed because of odr-use in a discarded statement (see [basic.def.odr] p12), and
  • the existence of a definition does not affect the semantics of the program because no constant-evaluation takes place (see [temp.inst] p8).

However, MSVC, GCC, and Clang reject this program. Only Clang rejects it for a lambda with -> void return type. It would be burdensome for users and implementors if this program was well-formed.

An instantiation might still be needed considering that the lambda can have a return type with a private destructor, or be [[nodiscard]], although the rules are unclear for this.

Suggested Resolution

In [smt.if] p2, re-define discarded statement to only apply within a templated entity:

 If the value of the converted condition
+of a constexpr if statement in an enclosing templated entity ([temp.pre])
 is false,
 the first substatement is a discarded statement.
 During the instantiation of an enclosing templated entity
-([temp.pre])
 ...

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