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

2024-03-20


2083. Incorrect cases of odr-use

Section: 6.3  [basic.def.odr]     Status: CD5     Submitter: Hubert Tong     Date: 2015-02-11

[Accepted as a DR at the February, 2019 meeting.]

The resolution of issue 1741 was not intended to cause odr-use to occur in cases where it did not do so previously. However, in an example like

  extern int globx;
  int main() {
    const int &x = globx;
    struct A {
     const int *foo() {
       return &x;
     }
    } a;
    return *a.foo();
  }

x satisfies the requirements for appearing in a constant expression, but applying the lvalue-to-rvalue converstion to x does not yield a constant expression. Similarly,

  struct A {
    int q;
    constexpr A(int q) : q(q) { }
    constexpr A(const A &a) : q(a.q * 2) { }
  };

  int main(void) {
    constexpr A a(42);
    constexpr int aq = a.q;
    struct Q {
     int foo() { return a.q; }
    } q;
    return q.foo();
  }

a satisfies the requirements for appearing in a constant expression, but applying the lvalue-to-rvalue conversion to a invokes a non-trivial function.

Proposed resolution (January, 2019):

  1. Change 6.3 [basic.def.odr] bullet 2.4 as follows:

  2. An expression is potentially evaluated unless it is an unevaluated operand (7.2 [expr.prop]) or a subexpression thereof. The set of potential results of an expression e is defined as follows:

  3. Change 6.3 [basic.def.odr] paragraph 4, converting the running text into bullets, as follows:

  4. A variable x whose name appears as a potentially-evaluated expression ex is odr-used by ex unless applying the lvalue-to-rvalue conversion (7.3.2 [conv.lval]) to x yields a constant expression (7.7 [expr.const]) that does not invoke a function other than a trivial special member function (11.4.4 [special]) and, if x is an object,

    This resolution also resolves issues 2103 and 2170.