C++ 未初始化和不确定之间的差异
我在看书 那里 讨论C++ 未初始化和不确定之间的差异,c++,c++11,C++,C++11,我在看书 那里 讨论未初始化的和不确定的值。想知道两者的区别吗 我的理解是,未初始化意味着编译器将分配内存,而不是试图初始化对象不确定->访问此对象可能会导致未定义的行为。 如果我错了,请纠正我 还想知道默认初始化和值初始化之间的区别,我认为您的解释很接近,但并不完全正确 未初始化表示内存已保留,但未填充有意义的数据。一个简单的例子: int* ptr; 所有这些只是保留一段内存来包含指针,但由于还没有int,指针的值不会改变,而是包含指向无意义位置的随机垃圾地址 另一个例子: class M
未初始化的
和不确定的
值。想知道两者的区别吗
我的理解是,未初始化
意味着编译器将分配内存,而不是试图初始化对象<代码>不确定->访问此对象可能会导致未定义的行为。
如果我错了,请纠正我
还想知道
默认初始化
和值初始化
之间的区别,我认为您的解释很接近,但并不完全正确
未初始化
表示内存已保留,但未填充有意义的数据。一个简单的例子:
int* ptr;
所有这些只是保留一段内存来包含指针,但由于还没有int,指针的值不会改变,而是包含指向无意义位置的随机垃圾地址
另一个例子:
class MyClass
{
int a;
int b;
MyClass() :
a(b) //Oops
b(5)
{ }
}
int b
用于a
时尚未初始化,并且再次包含随机垃圾
不确定
状态是指对象已初始化,但(可能是因为不再打算使用它)您不知道其中包含什么
它的行为是不可预测的,但不是无效的(当然,除非文档中说它也是无效的)。例如:
std::string a("text");
std::string b(std::move(a));
字符串a
现在可能只是一个空字符串。访问它不会导致未定义的行为,它的行为将类似于任何其他空字符串。除非你不确定它是空的
据你所知,它可能已经用对某个静态常量字符数组的引用替换了它的字符数组,并说“这是一个不确定的对象,你为什么要访问我,别管我。”
。或者一些复杂的看似随机的字符序列,这是内部优化的结果。你不知道里面有什么,也不应该使用它。但当你这样做时,它不会给你未定义的行为。只是在未定义的数据上的无用行为
默认初始化
和值初始化
不是您主要问题的一部分,您应该在单独的问题中询问这些问题(假设您在此网站上已经找不到答案)。在
WhozCraig。评论中有一个关于读取值的讨论。问题是关于C99;C++11标准本身没有定义“不确定值”的含义(至少不是草案文件)。我将总结一些相关部分
问题本身在C99中有不确定值的定义:
3.17.2
1不确定值
未指定的值或陷阱表示形式
链接的答案链接到另一个关于的好问题,以获取更多信息
Steve Jessop评论C或C++中的一个未确定的或未初始化的值的影响。
它的实现定义了int是否具有任何陷阱表示。如果没有(而且我从来没有实际使用过陷阱值为int的实现),那么读取不确定值就不是未定义的行为:您知道它不是陷阱值,所以它是int类型的有效值,只是未指定哪一个。相比之下,在C++中,它是显式的UB来读取任何未初始化的值。在C和C++中,都是UB来读取陷阱表示< /P>
我也从(CaldAdvutdial.com)中找到了关于C90、C99和C++('98和03)标准的评论。
75: C++ 对象可能具有不确定的值。但是,标准没有明确说明此值的属性 579: C90 C90标准规定读取未初始化的对象是未定义的行为。但是,它没有为任何其他表示指定未定义的行为 C++C++标准没有明确指定任何此类行为。
对于问题的最后一部分,在处有摘要,“未初始化”是属于对象的属性:已分配存储,但未存储任何值。“不确定”是属于某个值的属性:未指定该值具有该值类型的一组可能成员中的哪一个。在某些情况下,对未初始化的对象(读取对象的存储值)执行左值到右值转换的结果是一个不确定的值,而在其他情况下,这样做会导致未定义的行为。这个问题不特定于C++11,如果删除了该标记或添加了C++1y,我相信我可以提供一个比现在更好的答案。您希望将问题限制在C++11上有具体的原因吗?在您的
MyClass
示例中,a
不仅仅包含随机垃圾。整件事都是未定义的行为。@juanchopanza:当然。但对于大多数存在的每个实现,您得到的特定未定义行为都是随机垃圾。@n如果您不接受这个答案,您是否发现它有问题?安腾有陷阱值。