C + C++ = 未定义的行为

C + C++ = undefined behavior?

本文关键字:未定义 C++      更新时间:2023-10-16

可能的重复项:
我们如何解释表达式 (++x(+(++x(+(++x( 的结果?
未定义的行为和序列点

我有问题,当代码

U = C + C++;

对于标准类型和我自己的类型,以不同的方式运行。我有一个示例 http://ideone.com/4S1uA 其中我对 int 和我的类 Int 有不同的值,它们应该代表真实 Int 的工作方式。

是否可以使我的类的行为方式与标准 int 相同?此代码是否有未定义的行为?

为什么它是不可觑视的?C++具有操作优先级,因此应首先计算c++,因为它会更改 a 的值,因此对于加法,作为第一个参数应传递新值 a,而作为第二个参数传递旧值。对于类 Int,它是这样工作的,但对于标准 int 则不是。

此代码是否有未定义的行为?

是的。相对于副作用,计算操作数的顺序是不确定的。

该标准第6.5(2(节规定:

如果标量对象的副作用相对于同一标量

对象上的不同副作用或使用同一标量值的值计算未排序 对象,则行为未定义。如果有多个允许的排序 表达式的子表达式,如果这种未排序的一方,则行为未定义 效果发生在任何排序中。

由于int是标量类型,并且由于此处的副作用是未排序的,因此行为未定义。

你应该像这样编写代码:

U = 2*C;
C++;

是的,这是未定义的行为。不能在同时修改变量的语句中两次访问变量,因为未定义表达式"C"和表达式"C++"的计算顺序。

这里涉及的概念是序列点之一。引用维基百科文章中的开头一句话:

命令式编程中的序列点定义了计算机程序执行中的任何点,在该点上保证先前评估的所有副作用都将被执行,并且尚未执行后续评估的副作用。

在 C 语言中,+运算符创建序列点。因此,没有定义副作用的顺序。但是,在C++中,重载operator +是函数调用,它确实会创建序列点。这在副作用方面会产生不同的行为。请注意,虽然未指定函数参数的计算顺序,但所有副作用都在函数进入之前完成。因此,如果C + C++涉及重载的+运算符,则在执行+函数之前,C++副作用将应用于+的左参数。这与int值的情况不同,在右侧的副作用完成之前,可能会也可能不会评估左侧。