【问题标题】:What does the Standard mean by "unspecified value" in 12.1 p14?标准在 12.1 p14 中的“未指定值”是什么意思?
【发布时间】:2014-01-16 17:32:32
【问题描述】:

12.1 p14 中未指定值一词的确切含义是什么:

在构造一个const对象的过程中,如果对象的值 或其任何子对象通过不 从构造函数的 this 指针直接或间接获得, 如此获得的对象或子对象的值是未指定的。 [ 示例:

struct C;
void no_opt(C*);

struct C {
    int c;
    C() : c(0) { no_opt(this); }
};

const C cobj;

void no_opt(C* cptr) {
    int i = cobj.c * 100; // value of cobj.c is unspecified
    cptr->c = 1;
    cout << cobj.c * 100 // value of cobj.c is unspecified
         << ’\n’;
}

——结束示例]

我可以在 1.3.25 中找到未指明行为的定义:

未指明的行为
行为,对于格式良好的程序构造和正确的数据,这取决于实现

  • 我在 VS2010 中运行了这个 sn-p,我得到了上面两个表达式 cobj.c 的正确结果:第一个表达式为 0,最后一个表达式为 1。这里没有说明什么?

  • 未指定行为的定义是否适用于未指定的值,即,这是否意味着在另一个编译器中我可以获得不同的结果?

【问题讨论】:

    标签: c++ c++11 constructor language-lawyer


    【解决方案1】:

    我想说,关键是未指定的行为实现定义的行为有何不同:

    1.3.10
    实现定义的行为
    行为,对于格式良好的程序构造和正确的数据,这取决于实现和每个实现文档。

    1.3.25
    未指定的行为
    行为,对于格式良好的程序构造和正确的数据,这取决于实现

    未指定的值意味着不仅标准不需要特定的值,而且实现甚至不必记录(预期的)值(在这种情况下,值可能会改变不仅从实现到实现,而且从版本到版本,甚至从执行到执行)。这不同于实现定义的值。使用实现定义的值,您知道您将获得什么,但它因实现而异。使用未指定的值,您不知道会得到什么,因为它不一定记录在实现中,即使从执行到执行也是如此。

    【讨论】:

      【解决方案2】:

      你的解释是正确的。标准未指定该行为。您可以使用此编译器获得您期望的结果,但另一个编译器可能会给出不同的结果。如果您想将代码移植到另一个编译器,或者可能是您正在使用的编译器的另一个版本,则不应依赖此行为。

      【讨论】:

      • 我不会说 行为 是未指定的。您仍然使用cobj.c 检索值,不允许实现抛出异常或类似情况(也许该值可能是陷阱表示?)。
      • 实际上,未指定的结果可能会在您每次尝试时发生变化:DS9k 实现可能会选择在每次向客户演示软件时提供不合适的值,而它提供了您希望它在测试期间具有的值.
      • 我想知道这个规则的原因是否是由于对象是常量,也许一些编译器不允许更改对象的成员,在成员中初始化之后 -初始化列表。这是一个很好的解释吗?
      【解决方案3】:

      英文术语或多或少是逐字使用的:“未指定”意味着标准没有给出精确的语义,但程序不会变得未定义或格式错误。

      【讨论】:

        【解决方案4】:

        从字面上看,这意味着没有错误的答案。 cobj.c 可能是任何 int 值,这不会构成编译器或运行时中的错误。但实际上,我认为有两种可能性; &amp;cobjthis 是相同的,在这种情况下,一切都按照您的预期进行,或者它们不同,并且您正在访问 cobj 中的潜在垃圾数据。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2022-06-19
          • 1970-01-01
          • 2023-03-30
          • 2019-11-01
          • 1970-01-01
          • 2016-09-08
          • 2011-05-15
          • 1970-01-01
          相关资源
          最近更新 更多