9

C99標準には、char型とsigned char /unsignedchar型との互換性を否定するステートメントがあることがわかりました。

C99標準の注35:

Limits.hで定義されたCHAR_MINは、値0またはSCHAR_MINのいずれかを持ち、これを使用して2つのオプションを区別できます。選択に関係なく、charは他の2つのタイプとは別のタイプであり、どちらとも互換性がありません。

私の質問は、なぜ委員会が互換性を否定するのかということです。理論的根拠は何ですか?charがsignedcharまたはunsignedcharと互換性がある場合、何かひどいことが起こりますか?

4

2 に答える 2

11

ルーツはコンパイラの歴史にあります。80 年代には、本質的に 2 つの C 方言がありました。

  1. プレーン char が署名されている場所
  2. プレーン char が署名されていない場合

これらのうち、C89 が標準化すべきものはどれですか? C89 はどちらも標準化することを選択しませんでした。それは、標準化された人々がインストール ベースと呼ぶ、既に記述された C コードで行われた多数の仮定が無効になるためです。したがって、C89 は K&R と同じことを行いました。プレーン char の署名を実装定義のままにします。特定の署名が必要な場合は、char を修飾します。最近のコンパイラでは通常、オプションで方言を選択できます (例: gcc の-funsigned-char)。

(un)signed char とプレーン char の違いを無視した場合に発生する可能性のある「ひどい」ことは、これらの詳細を考慮せずに算術演算とシフトを行うと、予期しないときに符号拡張が発生する可能性があることです。逆もまた同様です(またはシフト時の未定義の動作でさえ)。

また、明示的な符号付きまたは符号なし修飾子を使用して常に文字を宣言することを推奨する愚かなアドバイスもあります。これは、そのような修飾された型へのポインターのみを操作する限り機能しますが、文字列と文字列関数を扱うとすぐに醜いキャストが必要になります。これらはすべて、プレーン文字へのポインターで動作します。キャスト。そのようなコードは、突然、骨の折れる大量の醜いキャストで埋め尽くされます。

文字の基本的なルールは次のとおりです。

  • 文字列にplaincharを使用し、プレーンcharを取る関数にポインタを渡す必要がある場合
  • unsigned charバイトのビット調整とシフトを行う必要がある場合に使用します
  • signed char小さな符号付きの値が必要な場合に使用しますがint、スペースが問題にならない場合は使用を検討してください
于 2012-10-07T14:18:15.260 に答える
2

と は、/のような最小の算術整数型signed charと考えてください。これらのタイプはすべて明確に指定されています。unsigned charsigned shortunsigned shortintlong intlong long int

一方、char非常に異なる目的を果たします。これは、基本的なタイプの I/O とシステムとの通信です。計算用ではなく、データの単位として使用されます。charコマンドライン引数、「文字列」の定義、FILE*関数、その他の読み取り/書き込みタイプの IO 関数、および厳密なエイリアシング規則の例外で使用されるのはそのためです。このchar型は、すべての実装で最も「自然な」表現を使用できるように、意図的にあまり厳密に定義されていません。

責任を分担するだけです。

(ただし、これはcharとの両方とレイアウト互換であるため、一方を他方に明示的に変換したり、元に戻したりすることができます。)signed charunsigned char

于 2012-10-07T14:12:43.207 に答える