[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 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 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*]