未初始化变量的后果:int vs unsigned char [英] Consequences of uninitialised variables: int vs unsigned char
问题描述
int x; // OK: the value of x is indeterminate
int y = x; // undefined behavior
在这里,int y = x;
是未定义的行为,因为x
未初始化.
但是
unsigned char c; // OK: the value of c is indeterminate
unsigned char d = c; // OK: the value of d is indeterminate
在这里,unsigned char d = c;
是不确定行为,但是unsigned char c;
也是未初始化的变量.
因此,为什么unsigned char d
的值不确定?
在线引用,例如 cppreference .com 在某种程度上是不错的.但是,众所周知,有时错误或误解有时会漏掉.因此,在处理这种奇怪情况时,采用官方的C ++标准总是一件好事.
N3936
§8.5初始化程序[dcl.init]
12 [...]使用自动或动态存储存储对象时 获得duration,则对象具有不确定的值,如果 没有对该对象执行初始化,该对象保留了 不确定的值,直到该值被替换(5.17). [...] 如果 不确定值是通过评估产生的,其行为是 未定义,但以下情况除外:
如果通过计算产生不确定的无符号窄字符类型值(3.9.1)
[...]
强制转换或转换为无符号窄字符类型(4.7、5.2.3、5.2.9、5.4)的操作数
[...]
则运算结果是一个不确定的值.
如果通过对简单赋值的右操作数求值产生了无符号的窄字符类型的不确定值 运算符(5.17),其第一个操作数是无符号窄的左值 字符类型,用不确定的值代替 左操作数引用的对象
如果通过初始化表达式的求值产生了无符号的窄字符类型的不确定值,则 初始化一个无符号窄字符类型的对象,该对象 初始化为不确定的值.
示例:
int f(bool b) { unsigned char c; unsigned char d = c; // OK, d has an indeterminate value int e = d; // undefined behavior return b ? d : 0; // undefined behavior if b is true }
因此(令我大吃一惊),该标准对此予以了支持.
为什么,最可能的原因也可以在标准中找到:
§3.9.1基本类型[basic.fundamental]
1 [...]对于无符号的窄字符类型,所有可能的位模式 值表示形式的代表数字. 这些要求确实 不适用于其他类型
作为旁注,我刚刚意识到这可以由邪恶的面试官使用:
问您能否以明确定义的行为将对象的有效值更改为不确定的值?如果是,怎么办?A.
unsigned char ind;
unsigned char x = 24;
x = ind; // x had a valid value, now x has an indetermined value
I saw the following example on cppreference.com
int x; // OK: the value of x is indeterminate
int y = x; // undefined behavior
Here, int y = x;
is undefined behavior because x
is uninitialized.
But,
unsigned char c; // OK: the value of c is indeterminate
unsigned char d = c; // OK: the value of d is indeterminate
Here, unsigned char d = c;
is indeterminate behavior, but unsigned char c;
is also an uninitialized variable.
So, Why is the value of unsigned char d
indeterminate?
Online references like cppreference.com are good up to a point. But it is known that sometimes errors or misinterpretations do occasionally slip through. So when dealing with such oddities, it is always a good thing to go to the official C++ standard.
N3936
§8.5 Initializers [dcl.init]
12 [...] When storage for an object with automatic or dynamic storage duration is obtained, the object has an indeterminate value , and if no initialization is performed for the object, that object retains an indeterminate value until that value is replaced (5.17). [...] If an indeterminate value is produced by an evaluation, the behavior is undefined except in the following cases:
If an indeterminate value of unsigned narrow character type (3.9.1) is produced by the evaluation of
[...]
the operand of a cast or conversion to an unsigned narrow character type (4.7, 5.2.3, 5.2.9, 5.4)
[...]
then the result of the operation is an indeterminate value.
If an indeterminate value of unsigned narrow character type is produced by the evaluation of the right operand of a simple assignment operator (5.17) whose first operand is an lvalue of unsigned narrow character type, an indeterminate value replaces the value of the object referred to by the left operand
If an indeterminate value of unsigned narrow character type is produced by the evaluation of the initialization expression when initializing an object of unsigned narrow character type, that object is initialized to an indeterminate value.
Example:
int f(bool b) { unsigned char c; unsigned char d = c; // OK, d has an indeterminate value int e = d; // undefined behavior return b ? d : 0; // undefined behavior if b is true }
So (to my big surprise) the standard backs this up.
As for why, the most likely reason can be also found in the standard:
§3.9.1 Fundamental types [basic.fundamental]
1 [...] For unsigned narrow character types, all possible bit patterns of the value representation represent numbers. These requirements do not hold for other types
As a side note, I just realized this can be used by an evil interviewer:
Q. Can you in a well-defined behavior change the valid value of an object to an undetermined value? If yes, how?
A.
unsigned char ind;
unsigned char x = 24;
x = ind; // x had a valid value, now x has an indetermined value
这篇关于未初始化变量的后果:int vs unsigned char的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!