4

標準 C プリプロセッサは "0xFFFFFFFF" をどのように解釈しますか: 4G-1 または -1?

「〜0」についても同じ質問...

答えが -1 の場合、それを 4G-1 として解釈するにはどうすればよいですか (つまり、明示的に 4294967295 を使用する以外に方法はありますか)?

PS:MS Visual Studioで試してみました(もちろん、「printf」を呼び出すのではなく比較を使用します。後者は指定された「%」に従って単純に印刷されるためです)、答えは4G-1でした。しかし、MS Visual Studio が標準の C プリプロセッサを使用しているかどうかはわかりません。

ありがとうございました

4

4 に答える 4

3

プリプロセッサに関する限り、0xFFFFFFFFは単なる 16 進数の定数です。#ifプリプロセッサ式 (およびディレクティブでのみ関連する#elif) の数値は、使用可能な最も広い整数型であると見なされます。プリプロセッサは、値が 2 32 -10xFFFFFFFFの符号付き整数定数として扱います(C99 以降では、少なくとも 64 ビットの整数型が常に存在するため)。4294967295

#iforディレクティブ以外の場所にある場合#elif、プリプロセッサは関係ありません。16 進定数の型は、次の最初のものです。

  • int
  • unsigned int
  • long int
  • unsigned long int
  • long long int
  • unsigned long long int

この特定の定数には、いくつかの可能性があります。

  • intが 32 ビットより狭く、32 ビットより広い場合long、型はlong;
  • intが 32 ビットより狭く、正確に 32 ビットの場合long、型はunsigned long;
  • intが 32 ビットの場合、タイプはunsigned int;
  • intが 32 ビットより広い場合、型はintです。

最新のシステムでunsigned intunsigned long、可能性が最も高いです。

すべての場合において、 の値0xFFFFFFFFは正確に 2 32 -1 または4294967295です。負の値になることはありません。

ただし、 の値を (明示的または暗黙的に)符号付きの型に変換する-1ことで、負の値 (たとえば)を簡単に取得できます。0xFFFFFFFF

int n = 0xFFFFFFFF;

しかし、これは移植性がありません。intが 32 ビットより広い場合、格納される値は 2 32 -1 になります。が正確に 32 ビットであってもint、符号なしの値を符号付きの型に変換した結果は実装定義です。-1は一般的な結果ですが、保証されていません。

に関しては~0、それintは値のすべてのビットが 1 に設定されている式です。これは通常 -1は ですが、保証されていません。

正確に何をしようとしていますか?

于 2013-10-23T03:26:54.867 に答える
2

C 2011 (N1570) 6.10.1 4 によると、プリプロセッサで評価される整数式は、実装 (intmax_tおよびuintmax_t) で最も広い型を使用します。0xFFFFFFFF各 C 実装はその値を としてサポートする必要があるため、値は 2 32 -1 になりますunsigned long~0通常の C 実装では、その値はありません。

#if式は、および#elifステートメントに対してのみプリプロセッサで評価されます。質問のテキストは、プリプロセッサの評価の結果として何らかの式を出力しようとしていることを示唆しています。それは起こりません。#ifandステートメントの外側のソース テキスト内の定数式は#elif、プリプロセッサではなく、通常の C 規則によって評価されます。

于 2013-10-23T02:47:46.287 に答える
1

ANSI C は、さまざまなコア データ型のサイズについてほとんど保証していないため、cpp上記の値を何らかの方法で移植可能に解釈することに依存するのは誤りです。押された場合は、チェックで包むことを検討してください。

#if 0xFFFFFFFF == -1
...
#else
...
#endif
于 2013-10-23T02:27:07.833 に答える
1

プリプロセッサは、強制されるまで数値を解釈しません。書き込み

 #define N  0xffffffff

プリプロセッサ評価Nを除いて、どこで使用されても単純なテキスト置換です。#ifC が値に対して行うことは、質問したいことである可能性がはるかに高くなります。例えば、

 long number = N;  // declare and initialize to symbolic value N

これにより、コンパイル警告が発生する場合と発生しない場合があります。また、a のサイズとlong、コンパイラが初期化定数をどの程度柔軟に変換するかによって、エラーが発生する場合もあります。

于 2013-10-23T02:29:06.693 に答える