C 和 in C++ 关于"^="运算符的区别

Difference between C and in C++ regarding the "^=" operator

本文关键字:运算符 区别 in C++ 关于      更新时间:2023-10-16

我想使用表达式交换int *xint *y指向的值

*x ^= *y ^= *x ^= *y;

(嗯,我知道这个表达很尴尬,我只是想知道区别,没有冒犯。这在C++中有效,但在 C 中失败。但是,如果我将其分为三个部分,如下所示

*x ^= *y;
*y ^= *x;
*x ^= *y;

它适用于两种语言。

那么,C和C++中的运算符^=有什么区别呢?

区别不在于您最初怀疑的指针,而在于评估规则的不同顺序。在"新"C++11"之前排序规则"中,我们有:

内置赋值运算符和所有内置复合赋值运算符的副作用(左参数的修改)在

左参数和右参数的值计算(但不是副作用)之后排序,并在赋值表达式的值计算之前(即,在返回对修改对象的引用之前)排序

(来自CPPR。此规则保证对表达式进行所需的从右到左计算。

与此相反,C 和 C++98 使用"序列点"。由于 long 语句中没有序列点,因此对指针指向的值进行了多次未排序的修改,从而调用了未定义的行为。

对于 C,gcc 对此发出警告(现场)。对于 C++98,它显然已经使用了新规则,这很好,因为未定义的行为是未定义的。

拆分语句当然可以解决这个问题,因为语句的末尾明确地在需要序列点的位置引入了序列点。它也是优越的,因为它更具可读性,并且不需要知道排序规则来确定代码是否正确。


供参考:可以在此处找到C++中排序规则的精彩解释。

在单个语句中多次修改同一变量是未定义的行为,因此当您执行*x ^= *y ^= *x ^= *y时,编译器可以执行任何操作。这与++i + i++之类的总是错误的原因相同。

要回答上述问题:C 和 C++ 之间的原始指针没有区别。

但我认为你真正的问题是别的...