未初始化和不确定性之间的区别

时间:2014-05-23 13:01:13

标签: c++ c++11

我正在阅读Do the parentheses after the type name make a difference with new

Michael Burr 讨论uninitializedindeterminate值。想知道它们之间的区别。

我的理解是,uninitialized意味着,编译器将分配内存而不是尝试初始化对象。 indeterminate - >访问此对象可能会导致未定义的行为。 如果我错了,请纠正我。

还想知道default-initializationvalue-initialization之间的区别。

2 个答案:

答案 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 ++标准没有明确指定任何此类行为。