Title
Definition of “indeterminate value”
Status
cd3
Section
Clause [3] [intro.defs]
Submitter
Bjarne Stroustrup

Created on 2007-02-02.00:00:00 last changed 123 months ago

Messages

Date: 2013-04-15.00:00:00

[Moved to DR at the April, 2013 meeting.]

Date: 2012-08-15.00:00:00

Additional note (August, 2012):

It was observed that the phrase in the fourth bullet of the change to 7.3.2 [conv.lval] paragraph 2 that reads “is not a local variable” should probably be changed to “does not have automatic storage duration,” because objects with static storage duration are zero-initialized and thus cannot have an indeterminate value. The issue was returned to "review" status for discussion of this point.

Date: 2012-10-15.00:00:00

Proposed resolution (October, 2012):

  1. Change 7.3.2 [conv.lval] paragraphs 1 and 2 as follows (including changing the running text of paragraph 2 into bullets):

  2. A glvalue (7.2.1 [basic.lval]) of a non-function, non-array type T can be converted to a prvalue.53 If T is an incomplete type, a program that necessitates this conversion is ill-formed. If the object to which the glvalue refers is not an object of type T and is not an object of a type derived from T, or if the object is uninitialized, a program that necessitates this conversion has undefined behavior. If T is a non-class type, the type of the prvalue is the cv-unqualified version of T. Otherwise, the type of the prvalue is T.54

    When an lvalue-to-rvalue conversion occurs in an unevaluated operand or a subexpression thereof (Clause 7 [expr]) the value contained in the referenced object is not accessed. In all other cases, the result of the conversion is determined according to the following rules:

    • If T is (possibly cv-qualified) std::nullptr_t, the result is a null pointer constant (7.3.12 [conv.ptr]).

    • Otherwise, if the glvalue T has a class type, the conversion copy-initializes a temporary of type T from the glvalue and the result of the conversion is a prvalue for the temporary.

    • Otherwise, if the object to which the glvalue refers contains an invalid pointer value (6.7.5.5.3 [basic.stc.dynamic.deallocation], _N4885_6.7.5.5.4 [basic.stc.dynamic.safety]), the behavior is implementation-defined.

    • Otherwise, if T is a (possibly cv-qualified) unsigned character type (6.8.2 [basic.fundamental]), and the object to which the glvalue refers contains an indeterminate value (7.6.2.8 [expr.new], 9.4 [dcl.init], 11.9.3 [class.base.init]), and that object does not have automatic storage duration or the glvalue was the operand of a unary & operator or it was bound to a reference, the result is an unspecified value. [Footnote: The value may be different each time the lvalue-to-rvalue conversion is applied to the object. An unsigned char object with indeterminate value allocated to a register might trap. —end footnote]

    • Otherwise, if the object to which the glvalue refers contains an indeterminate value, the behavior is undefined.

    • Otherwise, if the glvalue has (possibly cv-qualified) type std::nullptr_t, the prvalue result is a null pointer constant (7.3.12 [conv.ptr]). Otherwise, the value contained in the object indicated by the glvalue is the prvalue result.

  3. Change 7.6.1.5 [expr.ref] paragraph 4 second bullet as follows:

    • If E2 is a static data member...

    • ...If E1 is an lvalue, then E1.E2 is an lvalue; if E1 is an xvalue, then otherwise E1.E2 is an xvalue; otherwise, it is a prvalue. Let the notation...

    • If E2 is a (possibly overloaded) member function...

  4. Change 7.6.4 [expr.mptr.oper] paragraph 6 as follows:

  5. ...The result of a .* expression whose second operand is a pointer to a data member is of the same value category (7.2.1 [basic.lval]) as its first operand an lvalue if the first operand is an lvalue and an xvalue otherwise. The result of a .* expression whose second operand is a pointer to a member function...

This resolution also resolves issues 129, 240, 312, 623, and 1013.

(See also issue 1213.)

Date: 2007-02-02.00:00:00

The C++ Standard uses the phrase “indeterminate value” without defining it. C99 defines it as “either an unspecified value or a trap representation.” Should C++ follow suit?

In addition, 7.3.2 [conv.lval] paragraph 1 says that applying the lvalue-to-rvalue conversion to an “object [that] is uninitialized” results in undefined behavior; this should be rephrased in terms of an object with an indeterminate value.

History
Date User Action Args
2014-03-03 00:00:00adminsetstatus: drwp -> cd3
2013-10-14 00:00:00adminsetstatus: dr -> drwp
2013-05-03 00:00:00adminsetmessages: + msg4364
2013-05-03 00:00:00adminsetstatus: ready -> dr
2012-11-03 00:00:00adminsetstatus: review -> ready
2012-09-24 00:00:00adminsetmessages: + msg3887
2012-09-24 00:00:00adminsetstatus: ready -> review
2012-02-27 00:00:00adminsetstatus: review -> ready
2011-09-06 00:00:00adminsetmessages: + msg3496
2011-09-06 00:00:00adminsetstatus: open -> review
2007-02-02 00:00:00admincreate