Created on 2015-02-11.00:00:00 last changed 59 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 | |