C 不关心你的算法,也不知道你的变量是否会下溢,也不知道下溢是有意的还是偶然的。无符号整数的下溢/上溢是明确定义的行为,因此在这种情况下,编译器会很乐意按照您的指示去做:创建下溢。
一些细节:
unsigned int secondsLeft = (currentTickSeconds - prevTickSeconds ) ?
currentTickSeconds - prevTickSeconds :
60 - prevTickSeconds + currentTickSeconds;
如果我们用它们对应的类型替换这个表达式中的所有变量,我们得到:
unsigned int = (unsigned int - unsigned int) ?
unsigned int - unsigned int :
int - unsigned int + unsigned int;
C 关心的只是它的隐式类型提升规则。此表达式中有两条这样的规则:常规平衡(通常的算术转换)和 ?: 运算符的特殊平衡规则。
平衡规则规定,如果两个相同大小的整数是表达式的操作数,其中一个是无符号的,则有符号操作数将转换为无符号操作数。
unsigned int = (unsigned int - unsigned int) ? // no conversion needed
unsigned int - unsigned int : // no conversion needed
(int - unsigned int) // convert the int to unsigned int
+ unsigned int; // we get unsigned + unsigned, no conversion needed
然后将结果存储在一个无符号整数中。
然而,C 中有一个特殊的(奇怪的)规则,与条件运算符 ?: 相关。第二个操作数和第三个操作数是平衡的,就好像它们是同一表达式的运算符一样。因此,如果您有这种情况:
1 ? (signed int)x : (unsigned int)y;
那么结果将始终是无符号整数。这是因为 x 和 y 被视为同一操作的一部分,即使 y 从未在代码中使用。这可能会产生微妙的错误,在我看来,完全避免使用 ?: 操作符就足够了。