代码之家  ›  专栏  ›  技术社区  ›  Sebastian

读取不确定的值是否是未定义的行为?

  •  11
  • Sebastian  · 技术社区  · 14 年前

    这个问题是在对这个问题的答复的评论中提出的 Is C/C++ bool type always guaranteed to be 0 or 1 when typecast'ed to int?

    所讨论的代码分配一个(本地)数组 bool 不初始化它们的值。

    const int n = 100;
    bool b[n];
    

    很明显 b 是不确定的。

    一些评论者认为阅读。 b[0] 是未定义的行为。这是C++标准中的任何地方吗?我仍然坚信相反的观点:

    1. 显然已经分配了存储空间,并且基本bool类型的初始化已经完成,因为它没有构造函数。因此,这肯定不等同于取消对未初始化指针的引用,或对未初始化的非平凡对象调用方法/强制转换运算符。这些具体案例似乎已被标准所涵盖。

    2. 行为在C中确实是未定义的: What happens to a declared, uninitialized variable in C? Does it have a value? 一些受访者似乎把两者混淆了。

    3. 在最新的C++ 0x草稿中,我找不到任何定义。 不确定的值 尤其是没有定义允许访问这样的值来触发处理器陷阱。事实上,比亚恩·斯特劳斯特罗普并不确定什么是inderminate值: http://zamanbakshifirst.blogspot.com/2007/02/c-indeterminate-value.html

    4 回复  |  直到 7 年前
        1
  •  4
  •   Community Michael Schmitz    7 年前

    是的,形式上不确定值的rvalue转换是UB(除了 unsigned char ,最初我写的是“and variants”,但正如我所回忆的那样,形式上是1的补码有符号字符,其中可能负0可以用作陷阱值)

    我懒得为你做标准的段落查找,也懒得去关心那次的否决票

    然而,在实践中,只有一个问题(1)古老的架构,也许(2)64位系统。

    编辑 :oops,我现在似乎想起了一篇关于访问不确定字符的正式UB的博客文章和相关的缺陷报告。所以也许我得检查一下标准,+搜索博士。阿尔格,那得晚些时候,现在咖啡!

    编辑2 :Johannes Schaub很好地提供了这个 link to SO question 讨论了访问char的UB。所以,那就是我记得的地方!谢谢,约翰。

    干杯。,

        2
  •  6
  •   Community Michael Schmitz    7 年前

    这个问题的答案随着最新的C++ 1Y工作草案而改变。 N3946 )我们可以找到 here . 剖面图 8.5 初始化程序 段落 德意志北方银行 从C++ 03和C++ 11中改变了很多,现在包含了以下内容( 强调我的 ):

    如果没有为对象指定初始值设定项,则该对象是 默认初始化。 当用自动或 获取动态存储持续时间,对象具有 不确定 价值 ,如果没有对对象执行初始化,则 对象保留一个不确定的值,直到该值被替换为止 (5.17)。[注意:具有静态或线程存储持续时间的对象是 零初始化,见3.6.2。–尾注] 如果不确定值是 由评估产生,行为未定义,除了 以下情况 :

    接下来列出了一些例外情况 无符号窄字符类型 只是,我有一个完整的报价 Has C++1y changed with respect to the use of indeterminate values and undefined behavior? .

    所以对你来说 b 具有自动存储持续时间且未初始化,因此具有不确定值。所以评估 b[0] 确实是未定义的行为。

    以前我们需要使用左值到右值的转换来证明这是未定义的,但是这是有问题的,因为 the conversion is underspecified .

    请注意,不确定值在本节中是斜体化的,因此意味着它被定义在适当的位置,因此现在C++ 1Y实际上定义了这个术语。以前这个术语没有定义,这在 defect report 616 .

        3
  •  5
  •   UncleBens    14 年前

    打开 bool ,标准规定 3.9.1基本类型 :

    bool类型的值为true或 假的。

    脚注说明:

    以描述的方式使用bool值 按照国际标准 “未定义” 例如通过检查 未初始化的automatic的值 对象,可能导致其行为 犹如 这既不是真的,也不是假的。

        4
  •  0
  •   supercat    8 年前

    阅读一个不确定的值通常会导致不确定的行为,这不仅仅是一个“理论”问题。即使对于所有可能的位模式都定义了值的类型,也不应认为不确定值的行为方式不同于未指定值是“令人惊讶的”。例如,如果*p包含不确定值,并且除了 如图所示,代码:

    uint32_t x,y,z;
    ...
    x = *p;
    if (condition1) y=x;
    ... code that "shouldn't" affect *p if its value is defined
    if (condition2) z=x;
    

    可以重写为:

    if (condition1) y=*p;
    ... code that "shouldn't" affect *p if its value is defined
    if (condition2) z=*p;
    

    如果*p的值是不确定的,编译器就不会被禁止 两个“if”语句之间的代码修改了它的值。 例如,如果*p占用的存储器被“float”占用 在释放和重新malloc'ed之前,编译器可能会编写“float” 上述两个“if”语句之间的值。