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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions