-
Notifications
You must be signed in to change notification settings - Fork 7
Description
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])
...