Files
2025-10-25 03:02:53 +03:00

122 lines
5.9 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

[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.6Indeterminate storage")),
the bytes have [*indeterminate values*](#def:value,indeterminate "6.8.5Indeterminate and erroneous values[basic.indet]");
- [(1.2)](#1.2)
otherwise, the bytes have [*erroneous values*](#def:value,erroneous "6.8.5Indeterminate 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.1General"), [[expr.assign]](expr.assign "7.6.19Assignment 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.2Lvalue-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.2Static 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.2Fundamental types"))
or std::byte type ([[cstddef.syn]](cstddef.syn "17.2.1Header <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.16Conditional operator[expr.cond]"),
* [(2.1.2)](#2.1.2)
the right operand of a [comma expression](expr.comma "7.6.20Comma operator[expr.comma]"),
* [(2.1.3)](#2.1.3)
the operand of a cast or conversion ([[conv.integral]](conv.integral "7.3.9Integral conversions"), [[expr.type.conv]](expr.type.conv "7.6.1.4Explicit type conversion (functional notation)"), [[expr.static.cast]](expr.static.cast "7.6.1.9Static cast"), [[expr.cast]](expr.cast "7.6.3Explicit type conversion (cast notation)"))
to an unsigned ordinary character type
or std::byte type ([[cstddef.syn]](cstddef.syn "17.2.1Header <cstddef> synopsis")), or
* [(2.1.4)](#2.1.4)
a [discarded-value expression](expr.context#def:discarded-value_expression "7.2.3Context 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.19Assignment 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*]