0

私が誰かのコードを読んでみると、彼は明示的な型キャストをわざわざ書いていることがわかりました。

 #define ULONG_MAX ((unsigned long int) ~(unsigned long int) 0)

コードを書くとき

  1 #include<stdio.h>
  2 int main(void)
  3 {
  4         unsigned long int max;
  5         max = ~(unsigned long int)0;
  6         printf("%lx",max);
  7         return 0;
  8 }

それも同様に機能します。無意味なコーディングスタイルですか?

4

2 に答える 2

3

いくつかの理由から、あなたが読んだコードは非常に悪いものです。

  • まず第一に、ユーザーコードは決して定義すべきではありませんULONG_MAX。これは予約済みの識別子であり、コンパイラの実装によって提供される必要があります。

  • その定義は、プリプロセッサでの使用には適していません#if。そこでは、基本的な整数型の_MAXマクロを使用できる必要があります。

  • (unsigned long)0ただのがらくたです。その点で最近のすべての C 標準に準拠していないコンパイラがあることを知っ0ULていない限り、誰もが を使用する必要があります。(私は何も知りません。)

  • (理論的には) パディング ビットがある可能性がある~0ULため、その値にはEvenを使用しないでください。値のビット パターンを処理しないため、より適切です。符号なし整数型の保証された算術プロパティを使用します。は常に unsigned 型の最大値になります。そのため、パディング ビットがないことが絶対に確実なコンテキストでのみ使用できます。しかし、それをそのまま使用しても意味がありません。より良いサービスを提供します。unsigned long-1UL-1~unsigned long-1

  • あなたが観察したように、あることが知られている表現を「再キャスト」することunsigned longは、単に不必要です。それにバグがあるコンパイラは想像できません。

式の再キャストは、プリプロセッサで使用される場合は意味があるかもしれませんが、非常に制限された状況下でのみであり、そこでは異なる解釈がされます。

#if ((uintmax_t)-1UL) == SOMETHING
..
#endif

ここで、左側の値はUINTMAX_MAX、プリプロセッサおよび後のコンパイラ フェーズで評価されます。そう

#define UINTMAX_MAX ((uintmax_t)-1UL)

コンパイラの実装に適した定義です。

(uintmax_t)プリプロセッサの値を確認するには、内部にキャストではなく不明な識別子トークンが()あり、それが に評価されることを観察し0ます。マイナス記号はバイナリのマイナスとして解釈されるため、0-1ULどちらが符号なしであり、したがって型の最大値になります。ただし、そのトリックは、キャストに単一の識別子トークンが含まれている場合にのみ機能し、例のように3つ含まれている場合や、整数定数に-または+記号がある場合にのみ機能します。

于 2013-02-03T08:07:57.767 に答える
0

値の型が であることを確認しようとしてい0ますunsigned long。変数にゼロを割り当てると、適切な型にキャストされます。

この場合、 if0がたまたま an でない場合unsigned long~演算子はたまたま他の型に適用され、その結果がキャストされます。

コンパイラがそれ0shortまたはであると判断した場合、これは問題になりますchar

ただし、演​​算子のの型は同じままにする必要があります。~そのため、彼らは外側のキャストに対して過度に慎重になっていますが、おそらく内側のキャストは正当化されます.

もちろん、最初から正しいゼロ タイプを指定することもできます~0UL

于 2013-02-03T07:50:07.680 に答える