2013-05-03 26 views
6

C99標準のセクション7.18.4.1「最小幅の整数定数のマクロ」では、最小のデータ型に定数をキャストするために[U]INT[N]_C(x)と定義されているマクロがあります。 8,16,32,64。L、UL、LL、またはULL修飾子を代わりに使用できるので、これらのマクロはなぜ定義されていますか?例えば、少なくともの32ビット符号なし定数を使用する場合は、UINT32_C(42)の代わりに42ULと書くことができます。長いデータ型は少なくとも32ビット幅であるため、ポータブルでもあります。「最小幅の整数定数用のマクロ」の目的は何ですか?

これらのマクロの目的は何ですか?

+0

私は、あなたが固定サイズの整数型を作成するときに、int型の大きさやlong型のようなことを心配する必要がないと思います。 –

答えて

7

定数はULになる場合は、あなたは彼らがここ

#define myConstant UINT32_C(42) 

以降

printf("%" PRId32 " is %s\n", (hasproperty ? toto : myConstant), "rich"); 

広すぎになっていないことを確認する場所でそれらを必要とするだろう式はulongであり、variadic関数は、printfによって誤って解釈される64ビット値をスタックに置くことができます。

+0

したがって、いくつかの32ビットプラットフォームでlongが64ビットになることをお勧めしますか?したがって、printfのようないくつかの関数では問題になります。そうであれば、64ビット整数操作は32ビットで十分であるため、パフォーマンスにも影響します。 – obareey

+1

はい、プラットフォーム設計者が決定する必要があります。そして、幅の異なる整数演算の性能差を過大評価しないでください。最新のマシンでは、算術自体はありません。唯一の違いは、ループでこのような操作をたくさん行い、メモリへのアクセスがボトルネックになる場合です。逆に、現代のavxプロセッサーは32ビット操作と同じくらい速い256ビット操作を行います。したがって、一般に、指定された幅のタイプを選択することは悪い考えです。 'size_t'、' ptrdiff_t'などを使って、あなたがやっていることのセマンティクスに合ったものを作りましょう。 –

+0

静的な 'const uint32_t var = 0xFFFF0000; 'という16ビットコンパイラはありますか?var = 0x0000?定数のサイズについてC99とC89の仕様は何を表していますか? – Samuel

3

それらは、少なくともNの幅最小整数型を使用するので、UINT32_C(42)intが32ビット未満であるシステムに42ULにのみ等価です。 intが32ビット以上のシステムでは、UINT32_C(42)42Uに相当します。 shortが32ビット幅であるシステムを想像することもできます。この場合、UINT32_C(42)(unsigned short)42に相当します。

EDIT:@obareey標準ライブラリの実装のすべてではないにしても、ほとんどが標準のこの部分に準拠していない可能性が高いと思われます。 [glibc bug 2841] [glibc commit b7398be5]

+0

しかし、これらのプラットフォームでは、32ビットが短い場合は問題ありません。なぜなら、32ビット以上の最速整数なので、そうであると思います。今私は混乱している。 "UINTN_C(value)マクロは、標準のuint_leastN_t型に対応する整数定数式に展開するはずですが、32ビットARMコンパイラは" #define UINT8_C(x)(x ## u) "と" #define UINT16_C(x)(x ## u) "をキャストせずに実行します。 – obareey

+0

最小、最速ではありません。 – Oktalist

+0

これらのマクロのどれが実際にコードを移植性を高めるために実際どれくらい頻繁に使用されるのだろうと思いますか?符号付きの符号なし比較のようなもののセマンティクスには、非常に多くの奇妙で奇抜なコーナーケースがあります。どのようにしてそれらのすべてに対処することができるのか分かりません。例えば、 'uint32_t n'を指定すると、' n'がゼロの場合、 '(n-1) supercat

0

マクロは、本質的におそらく ような整数定数サフィックスを追加LLLUUL、基本的ことを除いて、対応する鋳造するためにそれらがほぼ同等になり、それらの引数にUL O接尾辞は決して落ちないでしょう。 LLP64アーキテクチャ上

例えば、 UINT32_C(42000000000)(41億)rules explained hereのタイプUL被写体を持っている、42000000000Uに変わります。一方、対応するキャスト((uint32_t)42000000000)は、uint32_t(LLP64ではunsigned int)に切り捨てられます。

私は良いユースケースとは思えませんが、動作するには少なくともXビットが必要な一般的なビットツイリングマクロで使用できると思いますが、余分なビットを削除したくない場合は、ユーザーは何か大きいものを渡します。

関連する問題