我尝试了以下代码作为实现单词R
和B
字节交换的天真尝试ABGR
#include <stdio.h>
#include <stdint.h>
uint32_t ABGR_to_ARGB(uint32_t abgr)
{
return ((abgr ^= (abgr >> 16) & 0xFF) ^= (abgr & 0xFF) << 16) ^= (abgr >> 16) & 0xFF;
}
int main()
{
uint32_t tmp = 0x11223344;
printf("%x %x\n", tmp, ABGR_to_ARGB(tmp));
}
令我惊讶的是,这段代码在 C++17 模式下的 GCC 中“有效”——字节被交换了
http://coliru.stacked-crooked.com/a/43d0fc47f5539746
但它不应该交换字节!C++17 明确指出,赋值的 RHS 应该在 LHS 之前 [完全] 排序,这也适用于复合赋值。这意味着在上面的表达式中,每个 RHS 都^=
应该使用 的原始值abgr
。因此,最终结果abgr
应该只是B
逐字节进行异或运算R
。这就是 Clang 似乎产生的(有趣的是,带有排序警告)
http://coliru.stacked-crooked.com/a/eb9bdc8ced1b5f13
快速浏览 GCC 程序集
显示它似乎是倒序排列的:LHS 在 RHS 之前。这是一个错误吗?或者这是海湾合作委员会的某种有意识的决定?还是我误解了什么?