Difference between C and in C++ regarding the “^=” operator

吃可爱长大的小学妹 提交于 2019-12-23 20:32:27

问题


I want to exchange the values pointed to by int *x and by int *y using the expression

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

(Well,I know this expression is awkward, and I just want to know the difference, no offense.) This worked in C++, but failed in C. However if I divide it into three parts, like below

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

It works fine for both languages.

So, what are the difference of the operator ^= in C and C++?


回答1:


The difference is not in the pointers as you initially suspected, but in the different order of evaluation rules. In the "new" C++11 "Sequenced-before rules", we have:

The side effect (modification of the left argument) of the built-in assignment operator and of all built-in compound assignment operators is sequenced after the value computation (but not the side effects) of both left and right arguments, and is sequenced before the value computation of the assignment expression (that is, before returning the reference to the modified object)

(From cppr.) This rule guarantees the desired right-to-left evaluation of your expression.

In contrast to this, C and C++98 use "Sequence points". Since there are no sequence points in the long statement, you have multiple unsequenced modification of the values the pointers point to and thus invoke Undefined Behavior.

For C, gcc warns about this (live). For C++98 it apparently uses the new rules already, which is fine because undefined behavior is undefined.

Splitting the statement solves this problem of course because the end of the statement explicitly introduces sequence points where you need them. It is also superior because it is more readable and one does not need to know sequencing rules to determine whether or not the code is correct.


For reference: A great explanation of sequencing rules in C++ can be found here.




回答2:


It is undefined behaviour to modify the same variable more than once in a single statement, so the compiler is allowed to do anything when you do *x ^= *y ^= *x ^= *y. It's the same reason why ++i + i++ or the like is always wrong.




回答3:


To answer the stated question: There's no difference for raw pointers between C and C++.

But I think your real question is something else...



来源:https://stackoverflow.com/questions/38421671/difference-between-c-and-in-c-regarding-the-operator

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!