「Cの完全なリファレンス」という本では、char
はデフォルトで符号なしであると述べられています。
しかし、Visual Studioと同様にGCCでこれを検証しようとしています。デフォルトではsignedとして取ります。
どちらが正しいか?
本は間違っています。標準では、プレーンchar
が署名されているか署名されていないかを指定していません。
実際、標準では、char
、signed char
、およびunsigned char
の3つの異なるタイプが定義されています。 #include <limits.h>
を見てからCHAR_MIN
を見ると、プレーンchar
がsigned
またはunsigned
(CHAR_MIN
が0または0に等しい)、しかし、それでも、標準に関する限り、つのタイプは区別されますです。
char
はこのように特別であることに注意してください。変数をint
として宣言する場合、signed int
として宣言することと100%同等です。これは、すべてのコンパイラとアーキテクチャに常に当てはまります。
Alokが指摘しているように、標準はそれを実装に任せています。
Gccの場合、デフォルトは署名されていますが、-funsigned-char
を使用して変更できます。 注意: Android NDKのgccの場合、デフォルトは符号なしです。 -fsigned-char
を使用して、署名された文字を明示的に要求することもできます。
MSVCでは、デフォルトは署名されていますが、/J
で変更できます。
C99 N1256ドラフト 6.2.5/15「タイプ」には、タイプchar
の署名の有無についての説明があります。
実装では、charを、signed charまたはunsigned charと同じ範囲、表現、および動作を持つように定義する必要があります。
そして脚注で:
CHAR_MIN
で定義されている<limits.h>
の値は0
またはSCHAR_MIN
のいずれかであり、これを使用して2つのオプションを区別できます。行われた選択に関係なく、char
は他の2つとは別のタイプであり、どちらとも互換性がありません。
ANSI Cの事実上の標準本であるデニスリッチーによるCプログラミング言語の本によると、署名付きまたは署名なしのプレーンな文字はマシン依存ですが、印刷可能な文字は常にポジティブです。
C標準によれば、プレーンなcharの署名は「実装定義」です。
一般に、実装者は、アーキテクチャ上で実装するのにより効率的な方を選択しました。 x86システムでは、通常charは署名されます。通常、アームシステムでは署名されていません(Apple iOSは例外です)。
Bjarne Stroustrupの「The C++ Programming Language」によると、char
は「実装定義」です。実装に応じて、signed char
またはunsigned char
になります。 std::numeric_limits<char>::is_signed
を使用して、char
が署名されているかどうかを確認できます。
これで、標準が実装に任せることがわかりました。
しかし、型を確認する方法は、signed
またはunsigned
のようなchar
ですか?
これを行うマクロを作成しました。
#define IS_UNSIGNED(t) ((t)~1 > 0)
gcc
、clang
、およびcl
でテストします。しかし、他の場合に常に安全かどうかはわかりません。