C 標準では、より小さい整数オペランドは、算術演算が実行される前int
に昇格されると指定されています。int
結果として、より小さい 2 つの符号なし値に対する操作int
は、符号なしではなく符号付きの演算で実行されます。32 ビット オペランドの操作が符号なし数学を使用して実行されることを保証することが重要な場合 (たとえば、積が 2⁶³ を超える可能性のある 2 つの数値を乗算する場合)、型の使用は、uint_fast32_t
未定義の動作なしで符号なしセマンティクスを生成するために、標準によって保証されます。 ? そうでない場合、少なくとも 32 ビットで、int
少なくとも
2 に答える
いいえ、ちがいます。いずれにせよ、[u]int_fastN_t
型をまったく使用しないことをお勧めします。実際のシステムでは、それらは誤って定義されています。たとえば、uint_fast32_t
通常 x86_64 では 64 ビット型として定義されますが、64 ビット演算はせいぜい (加算、減算、論理演算) 32 ビット演算と同じ速度であり、最悪の場合(除算、およびロード/ストア) ははるかに低速です。 2 倍のキャッシュ ラインを使用するため)。
C 標準はint
、少なくとも 16 ビットのみを必要とし、その幅に上限を設定しないため、uint_fast32_t
より狭くint
、同じ幅、またはより広くなる可能性があります。
たとえば、適合する実装では、int
64 ビットを作成uint_fast32_t
し、32 ビットの typedef を作成できますunsigned short
。または、逆に、int
16 ビットにすることもできますがuint_fast32_t
、名前が示すように、少なくとも 32 ビットにする必要があります。
興味深い結果の 1 つは、次のことです。
uint_fast32_t x = UINT_FAST32_MAX;
uint_fast32_t y = UINT_FAST32_MAX;
x * y;
オーバーフローし、未定義の動作が発生する可能性があります。たとえば、short
is が 32 ビットでint
is が 64 ビットの場合uint_fast32_t
、 の typedef になる可能性があり、乗算される前にsigned int にunsigned short
昇格します。ほぼ 2 64である結果は、 として表すには大きすぎます。int
POSIX ではint
andunsigned int
が少なくとも 32 ビットである必要がありますが、質問に対する答えは POSIX 準拠の実装でも変わりません。uint_fast32_t
また、int
それぞれ 32 ビットと 64 ビット、または 64 ビットと 32 ビットのいずれかである可能性があります。(後者は、64 ビット型が よりも高速であることを意味します。これは、「アーキテクチャによって提案された自然なサイズ」を持つことになっていることをint
考えると奇妙ですが、許可されています。)int
実際には、ほとんどのコンパイラ実装者は、定義済みの型で 8、16、32、および 64 ビットの整数をカバーしようとする傾向がありint
ます。これに従わない唯一のコンパイラは、Cray ベクトル マシン用でした。(拡張整数型はこれを回避できますが、それを利用するコンパイラは見たことがありません。)
そうでない場合、少なくとも 32 ビットで、
int
少なくとも
はいunsigned long
(unsigned long long
少なくとも 64 ビットです)。