我正在阅读Do the parentheses after the type name make a difference with new
有Michael Burr
讨论uninitialized
和indeterminate
值。想知道它们之间的区别。
我的理解是,uninitialized
意味着,编译器将分配内存而不是尝试初始化对象。 indeterminate
- >访问此对象可能会导致未定义的行为。
如果我错了,请纠正我。
还想知道default-initialization
和value-initialization
之间的区别。
答案 0 :(得分:3)
我认为您的解释很接近,但完全正确。
uninitialized
表示内存已保留,但未填充有意义的数据。一个简单的例子:
int* ptr;
所有这一切都是保留一块内存来包含指针,但由于还没有int,该指针的值不会被改变,并且包含一个无意义的垃圾地址到无意义的位置。
另一个例子:
class MyClass
{
int a;
int b;
MyClass() :
a(b) //Oops
b(5)
{ }
}
将{p> int b
用于a
并且再次包含随机垃圾时, indeterminate
尚未初始化。
std::string a("text");
std::string b(std::move(a));
状态是对象初始化的时间,但是(可能因为它不打算再被使用)你不知道它里面有什么。
它的行为是不可预测的,但不是无效的(当然,除非文档说它也是无效的)。例如:
string a
"this is an indeterminate object why are you accessing me leave me alone."
现在可能只是一个空字符串。访问它不会导致未定义的行为,它将表现得像任何其他空字符串。除非你不确定它是空的。
就你所知,它可能已经用对default-initialization
的一些静态const char数组的引用替换了它的char数组。或者是一些看似随机的复杂系列,是内部优化的结果。你无法知道它里面有什么,不应该使用它。但是当你这样做时,它不会给你未定义的行为。对未定义的数据只是无用的行为。
value-initialization
和{{1}}不是您主要问题的一部分,您应该在单独的问题中提出这些问题(假设您已经无法在此网站上找到答案)。
答案 1 :(得分:3)
What is Indeterminate value?有一个很好的答案 WhozCraig。关于阅读价值观的评论中有一个讨论。问题是关于C99; C ++ 11标准本身并没有定义“不确定值”的含义(至少不是草案文档)。我将总结一些相关的零件。
问题本身具有C99中不确定值的定义:
3.17.2
1不确定值
未指定的值或陷阱表示
链接的答案链接到另一个关于trap representation的好问题,以获取更多信息。
Steve Jessop评论了在C或C ++中读取不确定值或未初始化值的影响。
它是实现 - 定义int是否有任何陷阱表示。如果它没有(并且我从未实际使用过具有int值的陷阱值的实现),那么读取不确定值并不是未定义的行为:你知道它不是陷阱值,所以它是一个有效值int类型,它只是未指定哪一个。相比之下,在C ++中,显式UB可以读取任何未初始化的值。在C和C ++中,UB都是读取陷阱表示
我还从The New C Standard(coding-guidelines.com)找到了这些内容,这些内容评论了C90,C99和C ++('98和'03)标准。
75:
C ++
对象可能具有不确定的值。但是,该标准没有明确说明该值的属性。
579:
C90
C90标准规定读取未初始化的对象是未定义的行为。但是,它没有为任何其他表示指定未定义的行为。
C ++
C ++标准没有明确指定任何此类行为。