Created on 2015-02-11.00:00:00 last changed 47 months ago
Proposed resolution (January, 2019):
Change 6.3 [basic.def.odr] bullet 2.4 as follows:
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:
...
If e is a pointer-to-member expression (7.6.4 [expr.mptr.oper])
whose second operand is a constant expression, the set contains the potential results of the object expression....
Otherwise, the set is empty.
Change 6.3 [basic.def.odr] paragraph 4, converting the running text into bullets, as follows:
A variable x whose name appears as a potentially-evaluated expression e
xis odr-used by exunlessapplying 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,
x is a reference that is usable in constant expressions (7.7 [expr.const]), or
x is a variable of non-reference type that is usable in constant expressions and has no mutable subobjects, and e
xis an element of the set of potential results of an expressione, where eitherof non-volatile-qualified non-class type to which the lvalue-to-rvalue conversion (7.3.2 [conv.lval]) is appliedto e, ore isx is a variable of non-reference type, and e is an element of the set of potential results of a discarded-value expression (7.2 [expr.prop]) to which the lvalue-to-rvalue conversion is not applied.
[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.
History | |||
---|---|---|---|
Date | User | Action | Args |
2020-12-15 00:00:00 | admin | set | messages: + msg6347 |
2020-12-15 00:00:00 | admin | set | status: drafting -> cd5 |
2017-02-06 00:00:00 | admin | set | status: open -> drafting |
2015-02-11 00:00:00 | admin | create |