加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – 为什么XOR与整数交换会触发警告?

发布时间:2020-12-16 10:52:39 所属栏目:百科 来源:网络整理
导读:我输入了以下程序: #include stdio.hint main(void) { int a = 3; int b = 42; printf("a = %dnb = %dn",a,b); printf("Exchanging values.n"); a ^= b ^= a ^= b; printf("a = %dnb = %dn",b); return 0;} 没关系当我尝试编译它时,我得到了这个: $gc
我输入了以下程序:

#include <stdio.h>

int main(void) {
    int a = 3;
    int b = 42;

    printf("a = %dnb = %dn",a,b);

    printf("Exchanging values.n");
    a ^= b ^= a ^= b;

    printf("a = %dnb = %dn",b);

    return 0;
}

没关系当我尝试编译它时,我得到了这个:

$gcc test.c -o test -Wall -Wextra -ansi -pedantic-errors
test.c: In function ‘main’:
test.c:11: warning: operation on ‘a’ may be undefined

这几乎是标准代码,不是吗?

为什么会触发警告?据我所知,只要您使用C的标准实现,就默认为int实现按位XOR.

非常感谢你.

解决方法

变量a在表达式中用作左值两次.

请记住,x ^ = y实际上是x = x ^ y的快捷方式,这意味着读取第一个操作数,然后写入.

如果你从原始表达式中取出第一个操作,那很好,请参阅:

b ^= a ^= b;    // OK
/*    2    1    */

这里,a使用两次,b使用三次.由于赋值运算符是从右到左的关联,首先计算^ = b,仅读取变量b,读取变量a然后写入,并将结果(r1)传递给第二个操作.在第二次操作中,第二次读取b ^ = r1,b(给出与先前读取的值相同的值),然后写入.请注意,没有办法以不同的方式解释,没有未定义的行为.在上面的语句中,a只读取一次,b读取两次但两次读取都返回相同的值,a和b只写入一次.没关系.

当你向左边添加第三个赋值时,它就成了一个问题:

a ^= b ^= a ^= b;    // NOT OK
/*    3    2    1    */

现在,a被读取两次,一次是在操作1上,一次是在操作3上,也是在操作1和操作3上写入的.在操作3上返回什么值,原始值或操作1之后的值是什么?

聪明的程序员可能认为操作1在处理操作3之前完全执行,但这不是由标准定义的.它恰好适用于大多数编译器.在操作3中,编译器可以很好地返回与为操作1返回的a相同的值,从而导致错误的结果.这是未定义的行为.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读