charはデフォルトで署名されていますか、署名されていませんか?


158

「Cの完全なリファレンス」という本でcharは、デフォルトで署名されていないことが言及されています。

しかし、私はこれをGCCとVisual Studioで検証しようとしています。それはデフォルトで署名されているようにそれを取っています。

どちらが正しいか?


5
私が信頼する1つのCリファレンスブックは、Harbison&Steeleの「C:A Reference Manual」(careferencemanual.com)です。もちろん、標準は最後の言葉ですが、あまり判読できず、標準外の先行標準および一般的な(つまり、POSIX)使用についてのわずかな情報しか提供しません。Harbison&Steeleは非常に読みやすく、詳細で、おそらくほとんどのリファレンスよりも正確です。ただし、これもチュートリアルではないため、学習の初期段階にいる場合は、学習することはおそらくお勧めできません。
Michael Burr

15
あなたが読んでいる本はハーバート・シルトのC:The Complete Referenceだと思います。この本のレビューから(accu.informika.ru/accu/bookreviews/public/reviews/c/c002173.htm): 私はこの本を推薦するつもりはありません(あまりにも多くの人が私の意見を重視しすぎています)。彼の他の作品に合法的に投げかけられたのと同じ問題に値するとは思いません。 マイケルが言うように、はるかに良い参照はHarbison&Steeleです。
Alok Singhal、2013年

ここで私の2セント:char署名されていない可能性がintあるため、経験則として、を使用してを使用して値を読み取ると、getchar()が返されることがありEOFます。EOFは通常、-1またはその他の負の値として定義されunsignedます。宣言は次のとおりです。extern int getchar();ところで、この推奨事項は「C:A Reference Manual」の本からも引用されています。
Maxim Chetrusca 2014年

6
私が信頼する1つのC参照はISO / IEC 9899:2011です:-)
Jeff

3
@MaxChetrusca良いアドバイスですが根拠が悪いcharです。署名された場合でもint、戻り値を格納するために使用する必要があります。
Antti Haapala 2016

回答:


204

本は間違っています。標準では、プレーンcharが署名されているか、署名されていないかは指定されていません。

実際には、標準は、3つの異なるタイプを定義していますcharsigned charunsigned char。を#include <limits.h>見てCHAR_MINからを見ると、plain charsignedorであるかunsignedどうか(CHAR_MIN0未満または0に等しい場合)がわかりますが、それでも、標準に関する限り、3つのタイプは異なります。

この点でchar特別なことに注意してください。あなたは変数を宣言するとint、それはとしてそれを宣言することは100%と同等ですsigned int。これは、すべてのコンパイラとアーキテクチャに常に当てはまります。


1
@Alok:他の一部のデータ型については同じことが当てはまりません。たとえば、常にint意味しsigned intますよね?とは別にchar、他にどのようなデータ型に同じ混乱がありCますか?
Lazer

8
@eSKay:はい、char署名付きまたは署名なしの唯一のタイプです。 たとえばintと同等signed intです。
Alok Singhal、2009年

28
これにはヒステリックな、あの、歴史的な理由があります。Cの初期の段階で、「標準」は少なくとも2回フリップフロップされ、人気のある初期のコンパイラーの一部は他のコンパイラーに逆行しました。
Hot Licks

9
@AlokSinghal:タイプのビットフィールドがint符号付きまたは符号なしのどちらであるかを実装定義します。
キース・トンプソン

@KeithThompson訂正ありがとうございます。ビットフィールドタイプはあまり使用しないため、詳細については忘れがちです。
Alok Singhal 2014

68

以下のようAlokが指摘する、標準の葉は、その実装まで。

gccの場合、デフォルトは署名されていますが、で変更できます-funsigned-char注: Android NDKのgccの場合、デフォルトはunsignedです。で明示的に署名された文字を要求することもでき-fsigned-charます。

MSVCでは、デフォルトは署名されていますが、で変更できます/J


2
彼の本は通常MSVCユーザーを対象としているため、シルトの説明がMSVCの動作と一致しないのは興味深いことです。MSがある時点でデフォルトを変更したのでしょうか。
Michael Burr

1
コンパイラに依存するのではなく、プラットフォームに依存すると思いました。charは、当時のシステムが印刷可能な文字として使用していたものに準拠するために、「文字データ型」の3番目のタイプとして残されていると思いました。
-Spidey

10
GCCのドキュメントによると、それはマシンに依存するとしています:「マシンの種類ごとに、文字のデフォルトが設定されています。これは、デフォルトではunsigned charのようです。または、デフォルトではsigned charのようです。
Deduplicator

1
Androidのデフォルトはunsigned charであるというメモのソースを提供できますか?
フィリップ、2015年

1
@Spidey C標準では、コンパイラ、プラットフォーム、CPUアーキテクチャを実際に区別していません。それは「実装」の下でそれらをすべて一緒にまとめるだけです。
プラグウォッシュ2016年

35

C99 N1256ドラフト 6.2.5 / 15「タイプ」には、タイプの符号付きについて述べていcharます。

実装では、charを定義して、signed charまたはunsigned charと同じ範囲、表現、および動作を持たせます。

そして脚注で:

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


7

ANSI Cの事実上の標準の本であるDennis RitchieによるCプログラミング言語の本によると、署名付きまたは署名なしのプレーン文字はマシンに依存しますが、印刷可能な文字は常に正です。


9
印刷可能な文字が常にポジティブであるとは限りません。C標準では、基本実行文字セットのすべてのメンバーが負でない値を持つことを保証しています。
キース・トンプソン

7

C標準によれば、プレーンcharの署名は「実装定義」です。

一般に、実装者は、自分のアーキテクチャに実装するのにより効率的な方法を選択しました。x86システムでは、charは通常署名されています。アームシステムでは、通常、署名されていません(Apple iOSは例外です)。



2
@plugwash Tim Postがキーを紛失したため、あなたの回答はおそらく反対投票されました。しかし真剣に、答えが正しい(この場合は正しい)と確信している限り、単一の反対投票について心配する必要はありません。正当な理由なしに投稿が反対票を投じられたことが何度かありました。気にしないでください、時々人々は奇妙なことをするだけです。
ドナルドダック

1
署名されたcharがx86でより効率的なのはなぜですか?ソースはありますか?
martinkunev

2

Bjarne Stroustrupによる「C ++プログラミング言語」によると、char「実装定義」です。それはすることができsigned charたりunsigned char、実装に依存します。charを使用して、署名されてstd::numeric_limits<char>::is_signedいるかどうかを確認できます。


9
これはCの質問です。C ++は、異なる言語で、C ++の参照は、Cには関係ありません
MM

1

現在、標準はそれを実装に任せることがわかっています。

しかし、型をチェックする方法は、signedまたはunsignedなどcharです。

私はこれを行うためにマクロを書きました:

#define IS_UNSIGNED(t) ((t)~1 > 0)

そして、でそれをテストしgccclang、とcl。しかし、他の場合でも常に安全であるかどうかはわかりません。


通常のCHAR_MIN <0(またはwchar_tの場合WCHAR_MIN <0)の何が問題になっていますか?
OO Tiib
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.