|
3723 | 3723 | \end{note}
|
3724 | 3724 | \indextext{object lifetime|)}
|
3725 | 3725 |
|
3726 |
| -\rSec2[basic.indet]{Indeterminate values} |
| 3726 | +\rSec2[basic.indet]{Indeterminate and erroneous values} |
3727 | 3727 |
|
3728 | 3728 | \pnum
|
3729 | 3729 | \indextext{value!indeterminate}%
|
3730 | 3730 | \indextext{indeterminate value}%
|
3731 | 3731 | When storage for an object with automatic or dynamic storage duration
|
3732 |
| -is obtained, the object has an \defnadj{indeterminate}{value}, and if |
3733 |
| -no initialization is performed for the object, that object retains an |
3734 |
| -indeterminate value until that value is replaced\iref{expr.ass}. |
| 3732 | +is obtained, |
| 3733 | +the bytes comprising the storage for the object |
| 3734 | +have the following initial value: |
| 3735 | +\begin{itemize} |
| 3736 | +\item |
| 3737 | +If the object has dynamic storage duration, or |
| 3738 | +is the object associated with a variable or function parameter |
| 3739 | +whose first declaration is marked with |
| 3740 | +the \tcode{[[indeterminate]]} attribute\iref{dcl.attr.indeterminate}, |
| 3741 | +the bytes have \defnadjx{indeterminate}{values}{value}; |
| 3742 | +\item |
| 3743 | +otherwise, the bytes have erroneous values, |
| 3744 | +where each value is determined by the implementation |
| 3745 | +independently of the state of the program. |
| 3746 | +\end{itemize} |
| 3747 | +If no initialization is performed for an object (including subobjects), |
| 3748 | +such a byte retains its initial value |
| 3749 | +until that value is replaced\iref{dcl.init.general,expr.ass}. |
| 3750 | +If any bit in the value representation has an indeterminate value, |
| 3751 | +the object has an indeterminate value; |
| 3752 | +otherwise, if any bit in the value representation has an erroneous value, |
| 3753 | +the object has an erroneous value\iref{conv.lval}. |
3735 | 3754 | \begin{note}
|
3736 | 3755 | Objects with static or thread storage duration are zero-initialized,
|
3737 | 3756 | see~\ref{basic.start.static}.
|
3738 | 3757 | \end{note}
|
3739 | 3758 |
|
3740 | 3759 | \pnum
|
3741 |
| -If an indeterminate value is produced by an evaluation, |
3742 |
| -the behavior is undefined except in the following cases: |
| 3760 | +Except in the following cases, |
| 3761 | +if an indeterminate value is produced by an evaluation, |
| 3762 | +the behavior is undefined, and |
| 3763 | +if an erroneous value is produced by an evaluation, |
| 3764 | +the behavior is erroneous and |
| 3765 | +the result of the evaluation is the value so produced but is not erroneous: |
3743 | 3766 | \begin{itemize}
|
3744 | 3767 | \item
|
3745 |
| - If an indeterminate value of |
| 3768 | + If an indeterminate or erroneous value of |
3746 | 3769 | unsigned ordinary character type\iref{basic.fundamental}
|
3747 | 3770 | or \tcode{std::byte} type\iref{cstddef.syn}
|
3748 | 3771 | is produced by the evaluation of:
|
|
3759 | 3782 | \item
|
3760 | 3783 | a discarded-value expression\iref{expr.context},
|
3761 | 3784 | \end{itemize}
|
3762 |
| - then the result of the operation is an indeterminate value. |
| 3785 | + then the result of the operation is an indeterminate value or |
| 3786 | + that errorneous value, respectively. |
3763 | 3787 | \item
|
3764 |
| - If an indeterminate value of |
| 3788 | + If an indeterminate or erroneous value of |
3765 | 3789 | unsigned ordinary character type or \tcode{std::byte} type
|
3766 | 3790 | is produced by the evaluation of
|
3767 | 3791 | the right operand of a simple assignment operator\iref{expr.ass}
|
3768 | 3792 | whose first operand is an lvalue of
|
3769 | 3793 | unsigned ordinary character type or \tcode{std::byte} type,
|
3770 |
| - an indeterminate value replaces |
| 3794 | + an indeterminate value or that erroneous value, respectively, replaces |
3771 | 3795 | the value of the object referred to by the left operand.
|
3772 | 3796 | \item
|
3773 |
| - If an indeterminate value of unsigned ordinary character type |
| 3797 | + If an indeterminate or erroneous value of unsigned ordinary character type |
3774 | 3798 | is produced by the evaluation of the initialization expression
|
3775 | 3799 | when initializing an object of unsigned ordinary character type,
|
3776 | 3800 | that object is initialized to an indeterminate
|
3777 |
| - value. |
| 3801 | + value or that erroneous value, respectively. |
3778 | 3802 | \item
|
3779 | 3803 | If an indeterminate value of
|
3780 | 3804 | unsigned ordinary character type or \tcode{std::byte} type
|
3781 | 3805 | is produced by the evaluation of the initialization expression
|
3782 | 3806 | when initializing an object of \tcode{std::byte} type,
|
3783 |
| - that object is initialized to an indeterminate value. |
| 3807 | + that object is initialized to an indeterminate value or |
| 3808 | + that erroneous value, respectively. |
3784 | 3809 | \end{itemize}
|
| 3810 | +Converting an indeterminate or erroneous value of |
| 3811 | +unsigned ordinary character type or \tcode{std::byte} type |
| 3812 | +produces an indeterminate or erroneous value, respectively. |
| 3813 | +In the latter case, |
| 3814 | +the result of the conversion is the value of the converted operand. |
3785 | 3815 | \begin{example}
|
3786 | 3816 | \begin{codeblock}
|
3787 | 3817 | int f(bool b) {
|
3788 |
| - unsigned char c; |
3789 |
| - unsigned char d = c; // OK, \tcode{d} has an indeterminate value |
| 3818 | + unsigned char *c = new unsigned char; |
| 3819 | + unsigned char d = *c; // OK, \tcode{d} has an indeterminate value |
3790 | 3820 | int e = d; // undefined behavior
|
3791 | 3821 | return b ? d : 0; // undefined behavior if \tcode{b} is \tcode{true}
|
3792 | 3822 | }
|
| 3823 | + |
| 3824 | +int g(bool b) { |
| 3825 | + unsigned char c; |
| 3826 | + unsigned char d = c; // no erroneous behavior, but \tcode{d} has an erroneous value |
| 3827 | + |
| 3828 | + assert(c == d); // holds, both integral promotions have erroneous behavior |
| 3829 | + |
| 3830 | + int e = d; // erroneous behavior |
| 3831 | + return b ? d : 0; // erroneous behavior if \tcode{b} is \tcode{true} |
| 3832 | +} |
| 3833 | + |
| 3834 | +void h() { |
| 3835 | + int d1, d2; |
| 3836 | + |
| 3837 | + int e1 = d1; // erroneous behavior |
| 3838 | + int e2 = d1; // erroneous behavior |
| 3839 | + |
| 3840 | + assert(e1 == e2); // holds |
| 3841 | + assert(e1 == d1); // holds, erroneous behavior |
| 3842 | + assert(e2 == d1); // holds, erroneous behavior |
| 3843 | + |
| 3844 | + std::memcpy(&d2, &d1, sizeof(int)); // no erroneous behavior, but \tcode{d2} has an erroneous value |
| 3845 | + assert(e1 == d2); // holds, erroneous behavior |
| 3846 | + assert(e2 == d2); // holds, erroneous behavior |
| 3847 | +} |
3793 | 3848 | \end{codeblock}
|
3794 | 3849 | \end{example}
|
3795 | 3850 |
|
|
0 commit comments