Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/128.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
有C++;关于C+中使用不确定值和未定义行为的标准已更改+;14? < C++ >标准中包含了一个令人惊讶的例子:代码< >3.3.2> /Cord>声明点,其中用它自己的不确定值初始化代码>:_C++_C++11_Language Lawyer_Undefined Behavior_C++14 - Fatal编程技术网

有C++;关于C+中使用不确定值和未定义行为的标准已更改+;14? < C++ >标准中包含了一个令人惊讶的例子:代码< >3.3.2> /Cord>声明点,其中用它自己的不确定值初始化代码>:

有C++;关于C+中使用不确定值和未定义行为的标准已更改+;14? < C++ >标准中包含了一个令人惊讶的例子:代码< >3.3.2> /Cord>声明点,其中用它自己的不确定值初始化代码>:,c++,c++11,language-lawyer,undefined-behavior,c++14,C++,C++11,Language Lawyer,Undefined Behavior,C++14,这里,第二个x用它自己的(不确定)值初始化。 -[结束示例] Johannes对此问题的回答表明,这是未定义的行为,因为它需要从左值到右值的转换 在最新的C++14标准草案N3936中,该示例已更改为: 这里,第二个x用它自己的(不确定)值初始化。 -[结束示例] C++14中的不确定值和未定义行为是否发生了变化,从而导致了示例中的这种变化?是的,这种变化是由语言中的变化驱动的,如果通过求值生成不确定值,则会导致其行为未定义,但无符号窄字符除外 其拟议案文见1,并已纳入最新工作草案N3936:

这里,第二个x用它自己的(不确定)值初始化。 -[结束示例]

Johannes对此问题的回答表明,这是未定义的行为,因为它需要从左值到右值的转换

在最新的C++14标准草案
N3936
中,该示例已更改为:

这里,第二个x用它自己的(不确定)值初始化。 -[结束示例]


C++14中的不确定值和未定义行为是否发生了变化,从而导致了示例中的这种变化?

是的,这种变化是由语言中的变化驱动的,如果通过求值生成不确定值,则会导致其行为未定义,但无符号窄字符除外

其拟议案文见1,并已纳入最新工作草案
N3936

关于不确定值,最有趣的变化是第12节
8.5
,该节从:

如果没有为对象指定初始值设定项,则该对象默认为已初始化;如果未执行初始化,则具有自动或动态存储持续时间的对象具有不确定值。[注:静态或线程存储持续时间为零的对象初始化,见3.6.2.-结束说明]

到(我的):

如果没有为对象指定初始值设定项,则该对象为 默认值已初始化。当存储对象时,使用自动或 获取动态存储持续时间时,对象具有不确定的 值,并且如果没有对对象执行初始化,则 对象保留一个不确定的值,直到该值被替换为止 (5.17[解释性汇编])。[注意:具有静态或线程存储的对象 持续时间为零初始化,请参见3.6.2[basic.start.init].-end 注]如果评估产生不确定值,则 行为未定义,但以下情况除外

  • 如果通过计算以下各项产生无符号窄字符类型(3.9.1[basic.basic])的不确定值:

    • 条件表达式(5.16[expr.cond])的第二个或第三个操作数

    • 逗号的右操作数(5.18[expr.comma])

    • 转换为无符号窄字符类型(4.7[conv.integral]、5.2.3[expr.type.conv]、5.2.9)的强制转换或转换操作数 [expr.static.cast],5.4[expr.cast]),或

    • 丢弃的值表达式(第5条[expr])

    那么操作的结果是一个不确定的值

  • 如果右键求值产生无符号窄字符类型(3.9.1[basic.basic])的不确定值 简单赋值运算符(5.17[expr.ass])的操作数,其第一个 操作数是无符号窄字符类型的左值,是 不确定值替换由引用的对象的值 左操作数

  • 如果通过计算 初始化未签名的对象时的初始化表达式 窄字符类型,该对象初始化为不确定字符 值。

并包括以下示例:

[示例:

-[结束示例]

我们可以在其中找到当前文本,
N3937
C++14 DIS

C++1y之前的版本

<> P>有趣的是,在这个草案之前不像C C++使用了不确定值这个术语,甚至没有定义它()。我们必须依赖第4.1节中所述的左值到右值转换第1段,其中说明:

[…]如果对象未初始化,则需要此转换的程序具有未定义的行为。[…]


脚注:

  • 1787
    是的修订版,我们可以在

  • 在我看来,使用代码和引号进行适当的格式设置更容易,只需在不带空格和
    的情况下编写,然后选择文本并使用按钮或快捷方式(CTRL-K表示Kode,CTRL-Q表示引号)。@user2864740具体来说,基本类型可能有陷阱表示(例如,)这会对正在运行的程序造成可怕的影响。在C和C++中,这表示为未定义的行为类型。code>unsigned char被禁止使用陷阱表示,因此新示例定义了行为。@Casey:虽然这是事实,但这不是该规则的基本原理。特别是,所有整数无符号类型(根据模算术规则)都被间接禁止使用陷阱表示。但只有无符号窄字符类型才属于此特殊豁免……如果文件明确规定,则允许这些后果包括UB,但鼓励尽可能窄地说明后果。例如,对于读取未初始化的自动变量的后果,一个有用的定义是,它可能会在调试构建中陷入陷阱,否则将产生一个任意值,该值将毒害存储该变量的任何变量,因此该变量的值可能永远不会因任何原因在任何时候发生变化。相当严重的后果,但没有编译器那么严重……进行反向因果推断,这将导致它忽略任何可能导致变量在未初始化的情况下被读取的条件,特别是如果该值的唯一“用途”是将其向下返回
    int x = 12;
    { int x = x; }
    
    unsigned char x = 12;
    { unsigned char x = x; }
    
    int f(bool b) {
      unsigned char c;
      unsigned char d = c; // OK, d has an indeterminate value
      int e = d;           // undefined behavior
      return b ? d : 0;    // undefined behavior if b is true
    }