[basic.indet]

# 6 Basics [[basic]](./#basic)

## 6.8 Memory and objects [[basic.memobj]](basic.memobj#basic.indet)

### 6.8.5 Indeterminate and erroneous values [basic.indet]

[1](#1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L4119)

When storage for an object with automatic or dynamic storage duration
is obtained,
the bytes comprising the storage for the object
have the following initial value:

- [(1.1)](#1.1)

If the object has dynamic storage duration, or
is the object associated with a variable or function parameter
whose first declaration is marked with
the [[indeterminate]] attribute ([[dcl.attr.indet]](dcl.attr.indet "9.13.6 Indeterminate storage")),
the bytes have [*indeterminate values*](#def:value,indeterminate "6.8.5 Indeterminate and erroneous values [basic.indet]");

- [(1.2)](#1.2)

otherwise, the bytes have [*erroneous values*](#def:value,erroneous "6.8.5 Indeterminate and erroneous values [basic.indet]"),
where each value is determined by the implementation
independently of the state of the program[.](#1.sentence-1)

If no initialization is performed for an object (including subobjects),
such a byte retains its initial value
until that value is replaced ([[dcl.init.general]](dcl.init.general "9.5.1 General"), [[expr.assign]](expr.assign "7.6.19 Assignment and compound assignment operators"))[.](#1.sentence-2)

If any bit in the value representation has an indeterminate value,
the object has an indeterminate value;
otherwise, if any bit in the value representation has an erroneous value,
the object has an erroneous value ([[conv.lval]](conv.lval "7.3.2 Lvalue-to-rvalue conversion"))[.](#1.sentence-3)

[*Note [1](#note-1)*:

Objects with static or thread storage duration are zero-initialized,
see [[basic.start.static]](basic.start.static "6.10.3.2 Static initialization")[.](#1.sentence-4)

â *end note*]

[2](#2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L4148)

Except in the following cases,
if an indeterminate value is produced by an evaluation,
the behavior is undefined, and
if an erroneous value is produced by an evaluation,
the behavior is erroneous and
the result of the evaluation is the value so produced but is not erroneous:

- [(2.1)](#2.1)

  If an indeterminate or erroneous value of
 unsigned ordinary character type ([[basic.fundamental]](basic.fundamental "6.9.2 Fundamental types"))
 or std​::​byte type ([[cstddef.syn]](cstddef.syn "17.2.1 Header <cstddef> synopsis"))
 is produced by the evaluation of:
  * [(2.1.1)](#2.1.1)

the second or third operand of a [conditional expression](expr.cond "7.6.16 Conditional operator [expr.cond]"),

  * [(2.1.2)](#2.1.2)

the right operand of a [comma expression](expr.comma "7.6.20 Comma operator [expr.comma]"),

  * [(2.1.3)](#2.1.3)

the operand of a cast or conversion ([[conv.integral]](conv.integral "7.3.9 Integral conversions"), [[expr.type.conv]](expr.type.conv "7.6.1.4 Explicit type conversion (functional notation)"), [[expr.static.cast]](expr.static.cast "7.6.1.9 Static cast"), [[expr.cast]](expr.cast "7.6.3 Explicit type conversion (cast notation)"))
 to an unsigned ordinary character type
 or std​::​byte type ([[cstddef.syn]](cstddef.syn "17.2.1 Header <cstddef> synopsis")), or

  * [(2.1.4)](#2.1.4)

a [discarded-value expression](expr.context#def:discarded-value_expression "7.2.3 Context dependence [expr.context]"),

then the result of the operation is an indeterminate value or
 that erroneous value, respectively[.](#2.1.sentence-1)

- [(2.2)](#2.2)

  If an indeterminate or erroneous value of
 unsigned ordinary character type or std​::​byte type
 is produced by the evaluation of
 the right operand of a simple assignment operator ([[expr.assign]](expr.assign "7.6.19 Assignment and compound assignment operators"))
 whose first operand is an lvalue of
 unsigned ordinary character type or std​::​byte type,
 an indeterminate value or that erroneous value, respectively, replaces
 the value of the object referred to by the left operand[.](#2.2.sentence-1)

- [(2.3)](#2.3)

  If an indeterminate or erroneous value of unsigned ordinary character type
 is produced by the evaluation of the initialization expression
 when initializing an object of unsigned ordinary character type,
 that object is initialized to an indeterminate
 value or that erroneous value, respectively[.](#2.3.sentence-1)

- [(2.4)](#2.4)

  If an indeterminate value of
 unsigned ordinary character type or std​::​byte type
 is produced by the evaluation of the initialization expression
 when initializing an object of std​::​byte type,
 that object is initialized to an indeterminate value or
 that erroneous value, respectively[.](#2.4.sentence-1)

Converting an indeterminate or erroneous value of
unsigned ordinary character type or std​::​byte type
produces an indeterminate or erroneous value, respectively[.](#2.sentence-2)

In the latter case,
the result of the conversion is the value of the converted operand[.](#2.sentence-3)

[*Example [1](#example-1)*: int f(bool b) {unsigned char *c = new unsigned char; unsigned char d = *c; // OK, d has an indeterminate valueint e = d; // undefined behaviorreturn b ? d : 0; // undefined behavior if b is true}int g(bool b) {unsigned char c; unsigned char d = c; // no erroneous behavior, but d has an erroneous value assert(c == d); // holds, both integral promotions have erroneous behaviorint e = d; // erroneous behaviorreturn b ? d : 0; // erroneous behavior if b is true}void h() {int d1, d2; int e1 = d1; // erroneous behaviorint e2 = d1; // erroneous behavior assert(e1 == e2); // holds assert(e1 == d1); // holds, erroneous behavior assert(e2 == d1); // holds, erroneous behavior std::memcpy(&d2, &d1, sizeof(int)); // no erroneous behavior, but d2 has an erroneous value assert(e1 == d2); // holds, erroneous behavior assert(e2 == d2); // holds, erroneous behavior} â *end example*]
