Title
Definition of "odr-usable" ignores lambda scopes
Status
open
Section
6.3 [basic.def.odr]
Submitter
Hubert Tong

Created on 2024-03-20.00:00:00 last changed 1 week ago

Messages

Date: 2024-04-25.18:30:35

Suggested resolution:

Change in 6.3 [basic.def.odr] paragraph 10 as follows:

A local entity (6.1 [basic.pre]) is odr-usable in a scope (6.4.1 [basic.scope.scope]) if:
  • either the local entity is not *this, or an enclosing class or non-lambda function parameter scope exists and, if the innermost such scope is a function parameter scope, it corresponds to a non-static member function, and
  • for each intervening scope (6.4.1 [basic.scope.scope]) between the point at which the entity is introduced and the scope (where *this is considered to be introduced within the innermost enclosing class or non-lambda function definition scope), either:
    • the intervening scope is a block scope, or
    • the intervening scope is the function parameter scope of a lambda-expression, or
    • the intervening scope is the lambda scope of a lambda-expression that has a simple-capture naming the entity or has a capture-default, and the block scope of the lambda-expression is also an intervening scope.
If a local entity is odr-used in a scope in which it is not odr-usable, the program is ill-formed.
Date: 2024-05-03.07:29:26

(From submission #523.)

Consider:

  void f() {
    int x;
    [&] {
      return x;       // #1
    };
  }

The odr-use of x is ill-formed, because x is not odr-usable in that scope, because there is a lambda scope (6.4.5 [basic.scope.lambda]) between #1 and the definition of x.

A more involved example exhibits implementation divergence:

  struct A {
    A() = default;
    A(const A &) = delete;
    constexpr operator int() { return 42; }
  };
  void f() {
    constexpr A a;
    [=]<typename T, int = a> {};   // OK, not odr-usable from a default template argument, and not odr-used
  }
History
Date User Action Args
2024-04-25 18:30:35adminsetmessages: + msg7678
2024-03-20 00:00:00admincreate