关于“^ =”运算符的C和C ++之间的区别

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

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

(好吧,我知道这个表达很尴尬,我只是想知道它的区别,没有冒犯。)这在C ++中有效,但在C中失败了。但是如果我把它分成三部分,如下所示

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

它适用于两种语言。

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

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

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

(来自cppr 。)此规则保证对表达式进行所需的从右到左的评估。

与此相反,C和C ++ 98使用“序列点” 。 由于long语句中没有序列点,因此您对指针指向的值进行了多次无序修改,从而调用Undefined Behavior。

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

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


供参考:可以在此处找到C ++中排序规则的一个很好的解释。

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

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

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