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 が気にするのは、その暗黙的な型昇格規則だけです。この式には、通常のバランス (通常の算術変換) と ?: 演算子の特別なバランス ルールの 2 つのルールがあります。
バランス規則では、同じサイズの 2 つの整数が式のオペランドであり、そのうちの 1 つが符号なしである場合、符号付きオペランドは符号なしオペランドに変換されると規定されています。
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
そして、結果は unsigned int に格納されます。
ただし、C には、条件演算子 ?: に関連する特別な (奇妙な) ルールがあります。第 2 オペランドと第 3 オペランドは、同じ式の演算子であるかのようにバランスが取れています。したがって、このケースがある場合:
1 ? (signed int)x : (unsigned int)y;
結果は常に unsigned int になります。これは、コード内で y が使用されていないにもかかわらず、x と y が同じ操作の一部であるかのように扱われるためです。これは微妙なバグを引き起こす可能性があり、私の意見では、?: 演算子を完全に避けるのに十分な理由です。