c++标准在c++ 14中对不确定值和未定义行为的使用方面有改变吗?
Has C++ standard changed with respect to the use of indeterminate values and undefined behavior in C++14?
如初始化是否需要左值到右值转换中所述?int x = x;
是UB吗?c++标准在3.3.2
声明点一节中有一个令人惊讶的例子,其中int
用它自己的不确定值初始化:
int x = 12; { int x = x; }
这里第二个x用它自己的(不确定的)值初始化。- 结束示例]
Johannes对这个问题的回答表明这是一种未定义的行为,因为它需要左值到右值的转换。
在最新的c++ 14标准草案N3936
中,可以在这里找到这个例子已经更改为:
unsigned char x = 12; { unsigned char x = x; }
这里第二个x用它自己的(不确定的)值初始化。- 结束示例]
在c++ 14中,关于不确定的值和未定义的行为是否发生了一些变化,这些变化导致了示例中的变化?
是的,这种变化是由语言的变化所驱动的,如果计算产生一个不确定的值,那么它就是未定义行为,但是对于无符号窄字符有一些例外。
缺陷报告1787,其建议文本可在N39141中找到,最近于2014年被接受,并纳入最新的工作草案N3936
:
关于不确定值最有趣的变化是8.5
段12,从
如果对象没有指定初始化式,则默认初始化该对象;如果不进行初始化,自动或动态存储时长的对象的值不确定。[注意:具有静态或线程存储时间的对象是零初始化的,参见3.6.2。- 结束说明]
to (强调mine):
如果没有为对象指定初始化式,则该对象为default-initialized。当存储对象具有自动或获取动态存储时间,对象有一个不确定值,如果未对该对象进行初始化,则为对象保留一个不确定的值,直到该值被替换(5.17 [expr.ass])。[注意:具有静态或线程存储的对象。Duration为零初始化,参见3.6.2 [basic.start.init]。端如果求值产生一个不确定的值,则行为是未定义的,除了以下情况:
如果unsigned窄字符类型(3.9.1 [basic.fundamental])的不确定值由:
求值产生
条件表达式(5.16 [expr.cond])的第二个或第三个操作数,
逗号的右操作数(5.18 [expr.comma]),
强制转换或转换为无符号窄字符类型的操作数(4.7 [convr .integral], 5.2.3 [expr.type. type])。conv], 5.2.9[expr.static。[expr.cast]、5.4 [expr.cast])或
一个丢弃值表达式(条款5 [expr]),
则操作的结果为不确定值
如果右求值产生unsigned窄字符类型(3.9.1 [basic.fundamental])的不确定值简单赋值操作符(5.17 [expr.ass])的操作数,其第一个操作数是无符号窄字符类型的左值不确定的值将替换引用的对象的值
如果unsigned窄字符类型(3.9.1 [basic.fundamental])的不确定值由初始化unsigned对象时的初始化表达式窄字符类型,该对象初始化为不确定的价值。
,并包括以下示例:
(例子:
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 }
- 结束示例]
我们可以在N3936中找到这个文本,这是当前的工作草案,N3937
是C++14 DIS
。
c++ 1y
值得注意的是,在此草案之前,不像C总是有一个很好的定义不确定值的概念,c++使用术语不确定值甚至没有定义它(假设我们不能从C99中借用定义),也可以看到缺陷报告616。我们必须依赖于未明确规定的左值到右值转换,在c++ 11标准草案中,4.1
左值到右值转换段落1中有涉及,其中说:
[…[…]
如果对象未初始化,则需要进行此转换的程序具有未定义行为。
脚注:
-
1787
是缺陷报告616的修订版,我们可以在N3903 中找到信息
- GCC和Clang在与__builtin_constant_p相关的static_assert方面有所不同
- 为什么我的代码在指针方面停止运行?
- 你如何使std::变体的使用更"palatable",语法方面?
- 我需要 c++ 结构方面的帮助
- 我需要 c++ 结构方面的帮助
- 为什么我在虚幻引擎中的多态性和接口方面遇到问题?
- 为什么酷睿i5-6600在非方阵乘法方面比酷睿i9-9960X更快?
- printf() 和 std::cout 在指针方面的区别
- Boost.Python 在静态库方面失败
- 为什么python在循环方面胜过c++
- 在设计方面:重载vector类型的类成员的插入运算符
- 编译方面的问题.错误E0413、E0434、C2664、C2440
- 如果我提前将参数声明为变量而不是将它们内联写入函数调用,那有什么区别(在内存方面)?
- c++ 类中的静态常量变量和常量变量在存储方面是否有区别
- 在碰撞检测方面苦苦挣扎.如何正确检测碰撞?
- 虽然循环在输入方面表现得很奇怪
- 区域设置是否有定义负号的方面?
- 代码在虚拟函数和继承方面未按预期工作
- 如何在C ++(qt)代码中使用python脚本?(网页抓取方面)
- 在正确性或良好的代码结构方面,这种动态对象创建看起来如何