C言語は多くのオペレータは、「通常の算術変換」を行います - 変換はC99標準の6.3.1.8に概要が記載されています。整数オペランドの場合、最初にプロモーションが実行され、これが問題の原因となります。
intが元の型のすべての値を表すことができる場合、その値は、元の型のすべての値を表すことができる場合は、6.3.1.1(算術演算子/ブール、文字、および整数) int;それ以外の場合は、unsigned intに変換されます。これらを整数昇格と呼びます。他のすべての型は整数昇格によって変更されません。
プロモーションint
とunsigned int
(またはビットフィールド)未満ランクの整数型とオブジェクトまたは式にのみ適用されます。だからあなたのexressionで
:
t1 < t2-1
変数は、彼らがあなたのプラットフォーム上でint
がunsigned short
のすべての値を表すことができるので、int型に昇格さunsigned short
であっても。したがって、式はint
タイプを使用して評価され、アンダーフローは発生しません。式のt2-1
部分は負の1になります。
s1 < s2-1
それらはint
/unsigned int
より高い「ランク」を持っているので、unsigned long
型は、昇格されていないので、表現をからのアンダーフローと(符号なし算術演算を使用して評価される:式中
減算)、s2-1
部分式は負ではなく非常に大きな数と評価されます。
コメントにlitbと書かれている場合、プラットフォームにはint
が実装されています例)、プロは、unsigned short
(unsigned short
は少なくとも16ビットでなければならない)のすべての値を表すことができないので、の代わりにunsigned short
の動きはunsigned int
になります。その場合、if
の両方のステートメントはtrueと評価されます。
〜nairboon:あなたが編集を気にしないことを祈っています。あなたのコードを機能的に同じコードに置き換えても、エディタにコピー/ペーストして変更せずにコンパイルすることができます。 –
この結果は保証されていないことに注意してください。 intがintと同じ値の範囲を格納するマシンでは、宣言はintの代わりにunsigned intに変換されるため、両方のifの出力が表示されます。 –