无符号字符的位取反

3
这是一个与C99标准相关的问题,涉及到无符号字符的整数提升和按位取反。
在第6.5.3.3节中,它指出:
整数提升是在操作数上执行的,并且结果具有提升后的类型。如果提升后的类型是无符号类型,则表达式~E等价于该类型中可表示的最大值减去E。
当我说这意味着什么时,我的理解是:
unsigned int ui = ~ (unsigned char) ~0; // ui is now 0xFF00.

我的困惑源自与一位同事的讨论,他发现我们的编译器出现了以下行为。

unsigned char uc = 0;
unsigned char ucInverted = ~0;

if( ~uc == ~0 )              // True, obviously
if( ~ucInverted == ~(~0) )   // False as it evaluates to: 0xFF00 == 0x0000
if( ~uc == ucInverted )      // False as it evaluates to: 0xFFFF == 0x00FF
if( uc == ~ucInverted )      // False as it evaluates to: 0x0000 == 0xFF00

这种行为已经被gcc确认。
是否可能获得适当的预期字符比较,使得这些情况中的每一个都将计算为true?

阅读此答案,如果~0是陷阱表示,则行为未定义。 - Grijesh Chauhan
@GrijeshChauhan:这些是无符号的,在这种情况下,陷阱表示是不相关的。另请参见链接答案中链接的6.2.6.2中的脚注53。 - Hasturkun
2
@Hasturkun:~0 不是无符号的... - Oliver Charlesworth
@OliCharlesworth:没错。但据我所知,这仍不是一个问题,因为有措辞说明“对于有符号类型,除了作为异常情况(如溢出)的一部分之外,任何有效值上的算术运算都不会生成陷阱表示形式。” - Hasturkun
1个回答

2

~uc 是一个类型为 int 的值(值为 0xFFFF)。ucInverted 是一个类型为 unsigned char 的值(值为 0xFF),然后被升级为类型为 int 的值(值为 0x00FF)。因此它们是不相等的。

我猜你可以这样做:if ((unsigned char)~uc == ucInverted)。尽管两个操作数仍将进行升级,但在升级之前它们将具有相同的值。


对我来说,必须将无符号字符强制转换回无符号字符才能正确比较它与无符号字符,这似乎完全不合逻辑。难道只有我这样认为吗? - Kenneth
@Kenneth:一旦接受了~会导致类型提升,剩下的就完全合乎逻辑了 ;) - Oliver Charlesworth
1
“~uc” 很可能是 “signed int” 类型。 - Alexey Frunze
不,真正的促销将会针对“有符号整数”,而不是“无符号整数”(几乎所有架构都是如此)。而且,这也不是问题的答案。 - Jens Gustedt
@JensGustedt:是的,你说得对,整数提升会尽可能地支持signed。回答已经更新。(虽然我不确定你所说的“不是问题的答案”是什么意思?) - Oliver Charlesworth
我想,仅仅因为我不喜欢它并不能使它变得不真实 :) - Kenneth

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接