gpt4 book ai didi

c++ - bitwise not操作的编译器优化

转载 作者:太空狗 更新时间:2023-10-29 16:22:27 24 4
gpt4 key购买 nike

我有一个简单的函数来测试两个数组是否互为逆数组。除了 tmp 变量外,它们看起来完全相同。一个有效,另一个无效。我一辈子都弄不明白为什么编译器会优化它——如果它确实是一个优化问题(我的编译器是 IAR Workbench v4.30.1)。这是我的代码:

// this works as expected
uint8 verifyInverseBuffer(uint8 *buf, uint8 *bufi, uint32 len)
{
uint8 tmp;
for (uint32 i = 0; i < len; i++)
{
tmp = ~bufi[i];
if (buf[i] != tmp)
{
return 0;
}
}
return 1;
}

// this does NOT work as expected (I only removed the tmp!)
uint8 verifyInverseBuffer(uint8 *buf, uint8 *bufi, uint32 len)
{
for (uint32 i = 0; i < len; i++)
{
if (buf[i] != (~bufi[i]))
{
return 0;
}
}
return 1;
}

代码的第一个版本有效,第二个版本无效。谁能弄清楚为什么?或者进行一些测试来探测问题出在哪里?

最佳答案

您看到的情况是整数提升 规则的结果。任何时候在表达式中使用小于 int 的变量,该值都会被提升为 int 类型。

假设 bufi[i] 包含值 255。它的十六进制表示是 0xFF。然后,该值是 ~ 运算符的操作数。因此,该值将首先被提升为 int(假设它是 32 位)将具有值 0x000000FF,并将 ~ 应用于此给出你 0xFFFFFF00。然后将此值与类型为 uint8_tbuf[i] 进行比较。值 0xFFFFFF00 超出此范围,因此比较始终为假。

如果您将 ~ 的结果分配回 uint8_t 类型的变量,值 0xFFFFFF00 将转换为 0x00 。然后将此转换后的值与 buf[i] 进行比较。

所以你看到的行为不是优化的结果,而是语言的规则。按原样使用临时变量是解决此问题的一种方法。您还可以将结果转换为 uint8:

if(buf[i] != (uint8)(~bufi[i]))

或者屏蔽掉除最低位字节以外的所有字节:

if(buf[i] != (~bufi[i] & 0xff))

关于c++ - bitwise not操作的编译器优化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57823023/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com