Title
Are integer constant operands of a conditional-expression “used?”
Status
cd3
Section
6.3 [basic.def.odr]
Submitter
Mike Miller

Created on 2008-09-09.00:00:00 last changed 90 months ago

Messages

Date: 2011-03-15.00:00:00

Proposed resolution (March, 2011):

Divide 3.2 [basic.def.odr] paragraph 2 into two paragraphs and change as follows:

An expression is potentially evaluated unless it is an unevaluated operand (Clause 5) or a subexpression thereof. The set of potential results of an expression e is defined as:

  • if e is an id-expression (5.1.1 [expr.prim.general]), the set whose sole member is e,

  • if e is a class member access (5.2.5 [expr.ref]), the set of potential results of the object expression,

  • if e is a pointer-to-member expression (5.5 [expr.mptr.oper]) whose second operand is a constant expression, the set of potential results of the object expression,

  • if e has the form (e1), the set of potential results of e1,

  • if e is a glvalue conditional expression (5.16 [expr.cond]), the union of the set of potential results of the second operand and the set of potential results of the third operand,

  • if e is a comma expression (5.18 [expr.comma]), the set of potential results of the right operand,

  • otherwise, the empty set.

A variable whose name appears as a potentially-evaluated expression x is odr-used unless it is an object that satisfies the requirements for appearing in a constant expression (5.19) and an expression e whose set of potential results contains that x is either a discarded-value expression (Clause 5 [expr]) or the lvalue-to-rvalue conversion (4.1 [conv.lval]) is immediately applied to e. this is odr-used...

[Drafting note: this wording requires S::a to be defined if it is used in an expression like *&S::a.
Date: 2012-02-15.00:00:00

[Voted into the WP at the February, 2012 meeting; moved to DR at the October, 2012 meeting.]

Date: 2011-08-15.00:00:00

Proposed resolution (August, 2011):

Divide 6.3 [basic.def.odr] paragraph 2 into two paragraphs and change as follows:

An expression is potentially evaluated unless it is an unevaluated operand (Clause 5) or a subexpression thereof. The set of potential results of an expression e is defined as:

  • if e is an id-expression (_N4567_.5.1.1 [expr.prim.general]), the set whose sole member is e,

  • if e is a class member access (7.6.1.5 [expr.ref]), the set of potential results of the object expression,

  • if e is a pointer-to-member expression (7.6.4 [expr.mptr.oper]) whose second operand is a constant expression, the set of potential results of the object expression,

  • if e has the form (e1), the set of potential results of e1,

  • if e is a glvalue conditional expression (7.6.16 [expr.cond]), the union of the sets of potential results of the second and third operands,

  • if e is a comma expression (7.6.20 [expr.comma]), the set of potential results of the right operand,

  • otherwise, the empty set.

A variable x whose name appears as a potentially-evaluated expression ex is odr-used unless it x is an object that satisfies the requirements for appearing in a constant expression (7.7 [expr.const]) and ex is an element of the set of potential results of an expression e, where either the lvalue-to-rvalue conversion (7.3.2 [conv.lval]) is immediately applied to e, or e is a discarded-value expression (Clause Clause 7 [expr]). this is odr-used...

[Drafting note: this wording requires S::a to be defined if it is used in an expression like *&S::a.]
Date: 2008-09-09.00:00:00

In describing static data members initialized inside the class definition, 11.4.9.3 [class.static.data] paragraph 3 says,

The member shall still be defined in a namespace scope if it is used in the program...

The definition of “used” is in 6.3 [basic.def.odr] paragraph 1:

An object or non-overloaded function whose name appears as a potentially-evaluated expression is used unless it is an object that satisfies the requirements for appearing in a constant expression (7.7 [expr.const]) and the lvalue-to-rvalue conversion (7.3.2 [conv.lval]) is immediately applied.

Now consider the following example:

    struct S {
      static const int a = 1;
      static const int b = 2;
    };
    int f(bool x) {
      return x ? S::a : S::b;
    }

According to the current wording of the Standard, this example requires that S::a and S::b be defined in a namespace scope. The reason for this is that, according to 7.6.16 [expr.cond] paragraph 4, the result of this conditional-expression is an lvalue and the lvalue-to-rvalue conversion is applied to that, not directly to the object, so this fails the “immediately applied” requirement. This is surprising and unfortunate, since only the values and not the addresses of the static data members are used. (This problem also applies to the proposed resolution of issue 696.)

History
Date User Action Args
2014-03-03 00:00:00adminsetstatus: drwp -> cd3
2012-11-03 00:00:00adminsetstatus: dr -> drwp
2012-02-27 00:00:00adminsetstatus: ready -> dr
2011-09-06 00:00:00adminsetstatus: review -> ready
2011-04-10 00:00:00adminsetmessages: + msg3269
2010-02-16 00:00:00adminsetmessages: + msg2523
2010-02-16 00:00:00adminsetmessages: + msg2522
2010-02-16 00:00:00adminsetstatus: drafting -> review
2009-03-23 00:00:00adminsetstatus: open -> drafting
2008-09-09 00:00:00admincreate