在以下代码中,假定 unsigned char 比 int 窄。
int f(void) { int i = -2; unsigned char uc = 1; return (i + uc) < 17; }
该代码导致编译器在您使用 -xtransition 选项时发出以下警告:
line 6: warning: semantics of "<" change in ISO C; use explicit cast
加法运算结果的类型为 int(值保留)或 unsigned int(无符号保留),但二者之间的位模式不会更改。在二进制补码机器上:
i: 111...110 (-2) + uc: 000...001 ( 1) =================== 111...111 (-1 or UINT_MAX)
这种位表示法对应于 -1(对于 int)或 UINT_MAX(对于 unsigned int)。因此,如果结果的类型为 int,将使用有符号比较,并且小于测试为 true。如果结果的类型为 unsigned int,将使用无符号比较,并且小于测试为 false。
强制类型转换的加法用来指定这两种行为之中所期望的行为:
value preserving: (i + (int)uc) < 17 unsigned preserving: (i + (unsigned int)uc) < 17
由于不同的编译器对相同的代码选择不同的含义,因此该表达式存在歧义。强制类型转换的加法帮助阅读器并消除警告消息。
相同的 位字段值的提升存在同样的情况。在 ISO C 中,如果 int 或 unsigned int 位字段中的位数小于 int 中的位数,则提升的类型为 int;否则提升的类型为 unsigned int。在大多数较旧的 C 编译器中,对于显式无符号位字段,所提升的类型为 unsigned int,在其他情况下为 int。
强制类型转换的类似使用可以消除存在歧义的情况。