tmp/tmpudvwk4en/{from.md → to.md}
RENAMED
|
@@ -1,54 +1,108 @@
|
|
| 1 |
-
### Indeterminate values <a id="basic.indet">[[basic.indet]]</a>
|
| 2 |
|
| 3 |
When storage for an object with automatic or dynamic storage duration is
|
| 4 |
-
obtained, the
|
| 5 |
-
|
| 6 |
-
indeterminate value until that value is replaced [[expr.ass]].
|
| 7 |
|
| 8 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 9 |
zero-initialized, see [[basic.start.static]]. — *end note*]
|
| 10 |
|
| 11 |
-
|
| 12 |
-
undefined
|
|
|
|
|
|
|
| 13 |
|
| 14 |
-
- If an indeterminate value of unsigned ordinary character
|
| 15 |
-
[[basic.fundamental]] or `std::byte` type [[cstddef.syn]] is
|
| 16 |
-
by the evaluation of:
|
| 17 |
- the second or third operand of a conditional expression
|
| 18 |
[[expr.cond]],
|
| 19 |
- the right operand of a comma expression [[expr.comma]],
|
| 20 |
- the operand of a cast or conversion
|
| 21 |
[[conv.integral]], [[expr.type.conv]], [[expr.static.cast]], [[expr.cast]]
|
| 22 |
to an unsigned ordinary character type or `std::byte` type
|
| 23 |
[[cstddef.syn]], or
|
| 24 |
- a discarded-value expression [[expr.context]],
|
| 25 |
|
| 26 |
-
then the result of the operation is an indeterminate value
|
| 27 |
-
|
| 28 |
-
|
| 29 |
-
|
| 30 |
-
|
| 31 |
-
|
| 32 |
-
|
| 33 |
-
|
| 34 |
-
|
| 35 |
-
|
| 36 |
-
|
|
|
|
|
|
|
|
|
|
| 37 |
- If an indeterminate value of unsigned ordinary character type or
|
| 38 |
`std::byte` type is produced by the evaluation of the initialization
|
| 39 |
expression when initializing an object of `std::byte` type, that
|
| 40 |
-
object is initialized to an indeterminate value
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 41 |
|
| 42 |
[*Example 1*:
|
| 43 |
|
| 44 |
``` cpp
|
| 45 |
int f(bool b) {
|
| 46 |
-
unsigned char c;
|
| 47 |
-
unsigned char d = c;
|
| 48 |
int e = d; // undefined behavior
|
| 49 |
return b ? d : 0; // undefined behavior if b is true
|
| 50 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 51 |
```
|
| 52 |
|
| 53 |
— *end example*]
|
| 54 |
|
|
|
|
| 1 |
+
### Indeterminate and erroneous values <a id="basic.indet">[[basic.indet]]</a>
|
| 2 |
|
| 3 |
When storage for an object with automatic or dynamic storage duration is
|
| 4 |
+
obtained, the bytes comprising the storage for the object have the
|
| 5 |
+
following initial value:
|
|
|
|
| 6 |
|
| 7 |
+
- If the object has dynamic storage duration, or is the object
|
| 8 |
+
associated with a variable or function parameter whose first
|
| 9 |
+
declaration is marked with the `[[indeterminate]]` attribute
|
| 10 |
+
[[dcl.attr.indet]], the bytes have *indeterminate values*;
|
| 11 |
+
- otherwise, the bytes have *erroneous values*, where each value is
|
| 12 |
+
determined by the implementation independently of the state of the
|
| 13 |
+
program.
|
| 14 |
+
|
| 15 |
+
If no initialization is performed for an object (including subobjects),
|
| 16 |
+
such a byte retains its initial value until that value is replaced
|
| 17 |
+
[[dcl.init.general]], [[expr.assign]]. If any bit in the value
|
| 18 |
+
representation has an indeterminate value, the object has an
|
| 19 |
+
indeterminate value; otherwise, if any bit in the value representation
|
| 20 |
+
has an erroneous value, the object has an erroneous value.
|
| 21 |
+
|
| 22 |
+
[*Note 1*: Lvalue-to-rvalue conversion has undefined behavior if the
|
| 23 |
+
erroneous value of an object is not valid for its type
|
| 24 |
+
[[conv.lval]]. — *end note*]
|
| 25 |
+
|
| 26 |
+
[*Note 2*: Objects with static or thread storage duration are
|
| 27 |
zero-initialized, see [[basic.start.static]]. — *end note*]
|
| 28 |
|
| 29 |
+
Except in the following cases, if an indeterminate value is produced by
|
| 30 |
+
an evaluation, the behavior is undefined, and if an erroneous value is
|
| 31 |
+
produced by an evaluation, the behavior is erroneous and the result of
|
| 32 |
+
the evaluation is the value so produced but is not erroneous:
|
| 33 |
|
| 34 |
+
- If an indeterminate or erroneous value of unsigned ordinary character
|
| 35 |
+
type [[basic.fundamental]] or `std::byte` type [[cstddef.syn]] is
|
| 36 |
+
produced by the evaluation of:
|
| 37 |
- the second or third operand of a conditional expression
|
| 38 |
[[expr.cond]],
|
| 39 |
- the right operand of a comma expression [[expr.comma]],
|
| 40 |
- the operand of a cast or conversion
|
| 41 |
[[conv.integral]], [[expr.type.conv]], [[expr.static.cast]], [[expr.cast]]
|
| 42 |
to an unsigned ordinary character type or `std::byte` type
|
| 43 |
[[cstddef.syn]], or
|
| 44 |
- a discarded-value expression [[expr.context]],
|
| 45 |
|
| 46 |
+
then the result of the operation is an indeterminate value or that
|
| 47 |
+
erroneous value, respectively.
|
| 48 |
+
- If an indeterminate or erroneous value of unsigned ordinary character
|
| 49 |
+
type or `std::byte` type is produced by the evaluation of the right
|
| 50 |
+
operand of a simple assignment operator [[expr.assign]] whose first
|
| 51 |
+
operand is an lvalue of unsigned ordinary character type or
|
| 52 |
+
`std::byte` type, an indeterminate value or that erroneous value,
|
| 53 |
+
respectively, replaces the value of the object referred to by the left
|
| 54 |
+
operand.
|
| 55 |
+
- If an indeterminate or erroneous value of unsigned ordinary character
|
| 56 |
+
type is produced by the evaluation of the initialization expression
|
| 57 |
+
when initializing an object of unsigned ordinary character type, that
|
| 58 |
+
object is initialized to an indeterminate value or that erroneous
|
| 59 |
+
value, respectively.
|
| 60 |
- If an indeterminate value of unsigned ordinary character type or
|
| 61 |
`std::byte` type is produced by the evaluation of the initialization
|
| 62 |
expression when initializing an object of `std::byte` type, that
|
| 63 |
+
object is initialized to an indeterminate value or that erroneous
|
| 64 |
+
value, respectively.
|
| 65 |
+
|
| 66 |
+
Converting an indeterminate or erroneous value of unsigned ordinary
|
| 67 |
+
character type or `std::byte` type produces an indeterminate or
|
| 68 |
+
erroneous value, respectively. In the latter case, the result of the
|
| 69 |
+
conversion is the value of the converted operand.
|
| 70 |
|
| 71 |
[*Example 1*:
|
| 72 |
|
| 73 |
``` cpp
|
| 74 |
int f(bool b) {
|
| 75 |
+
unsigned char *c = new unsigned char;
|
| 76 |
+
unsigned char d = *c; // OK, d has an indeterminate value
|
| 77 |
int e = d; // undefined behavior
|
| 78 |
return b ? d : 0; // undefined behavior if b is true
|
| 79 |
}
|
| 80 |
+
|
| 81 |
+
int g(bool b) {
|
| 82 |
+
unsigned char c;
|
| 83 |
+
unsigned char d = c; // no erroneous behavior, but d has an erroneous value
|
| 84 |
+
|
| 85 |
+
assert(c == d); // holds, both integral promotions have erroneous behavior
|
| 86 |
+
|
| 87 |
+
int e = d; // erroneous behavior
|
| 88 |
+
return b ? d : 0; // erroneous behavior if b is true
|
| 89 |
+
}
|
| 90 |
+
|
| 91 |
+
void h() {
|
| 92 |
+
int d1, d2;
|
| 93 |
+
|
| 94 |
+
int e1 = d1; // erroneous behavior
|
| 95 |
+
int e2 = d1; // erroneous behavior
|
| 96 |
+
|
| 97 |
+
assert(e1 == e2); // holds
|
| 98 |
+
assert(e1 == d1); // holds, erroneous behavior
|
| 99 |
+
assert(e2 == d1); // holds, erroneous behavior
|
| 100 |
+
|
| 101 |
+
std::memcpy(&d2, &d1, sizeof(int)); // no erroneous behavior, but d2 has an erroneous value
|
| 102 |
+
assert(e1 == d2); // holds, erroneous behavior
|
| 103 |
+
assert(e2 == d2); // holds, erroneous behavior
|
| 104 |
+
}
|
| 105 |
```
|
| 106 |
|
| 107 |
— *end example*]
|
| 108 |
|