[迷信] char 型は符号付き
short, int, long と同じく、signed も unsigned も付けなければ、デフォルトで符号付きという類推が働くからか、あるいは普段使っている処理系がたまたまそうだったからか、char 型の表現範囲は -128〜+127 であると堅く信じているプログラマは少なくありません。
[迷信] 1 バイトは 8 ビットでも指摘したように、char 型は 8 ビットとは限りません。それだけでなく、char 型は符号付きか符号無しかも処理系定義です。ですので、char 型が -128〜+127 であるという決めつけは、これら二つの意味で間違っています。
6.2.5 型 (中略)
三つの型char, signed char及びunsigned charを総称して文字型(character type)と呼ぶ。処理系は,charを,signed char又はunsigned charのいずれかと同じ値の範囲,同じ表現形式,そして同じ動作をするものとして定義しなければならない。JIS X3010:2003より引用
3.9.1 基本型 文字(char)として宣言されたオブジェクトの大きさは,処理系定義である基本文字集合のすべての要素を格納するのに十分なだけ大きくなければならない。(中略)charオブジェクトが負の値をもてるか否かは,処理系定義とする。
JIS X3014:2003より引用
二つの規格から引用しました。上段は標準 C、下段は標準 C++ の規定です。いずれも、char 型が符号付きか符号無しかは処理系定義であることが明記されています。
ところで、処理系定義というと、コンパイラが決まれば char 型が符号付きか符号無しかが決まるように考えてしまいがちです。しかし、現実はそれほど単純ではありません。例えば、GCC の場合には、ターゲットによって char 型が符号付きか符号無しかが変わります。
また、コンパイルオプションによっても変わります。例えば、GCC の場合、-funsigned-char または -fsigned-char オプションを指定することで、char 型が符号無しなのか符号付きなのかを設定できます。Visual C++ では、デフォルトでは符号付きですが、/J オプションを指定すれば符号無しになります。
日本語のように、多バイト文字を多用する言語環境の場合、char 型は符号無しの方が何かと便利です。では、unsigned char を使えばよいかというと、C の場合はそれでもかまいませんが、C++ ではそうはいきません。単なる char、signed char、および unsigned char はそれぞれ別の型だからです。型が異なるということは、多重定義やテンプレートの解決に影響しますので、unsigned char を使うというわけにはいかないのです。
参考
トラックバック
ブックナビゲーション
- 技術情報
- Boost C++ Libraries メモ
- C++と組込み環境
- C++サンプル集
- C++テンプレート集
- C++プログラマのためのC言語入門
- C/C++迷信集
- [迷信] 'A'~'Z' の値は連続している
- [迷信] 0xe-0xe はゼロ
- [迷信] 1 バイトは 8 ビット
- [迷信] 2の累乗による割り算と右シフトは等価
- [迷信] FILE 型は構造体
- [迷信] abs は常に非負の値を返す
- [迷信] argv[0] はプログラム名
- [迷信] char 型は符号付き
- [迷信] double の出力書式は "%lf"
- [迷信] fflush で入力バッファをクリア
- [迷信] free でメモリを開放する
- [迷信] free に NULL を渡すとクラッシュする
- [迷信] gets は単純に fgets に置き換えられる
- [迷信] isalpha 関数の引数は char 型
- [迷信] new に失敗すると NULL が返る。
- [迷信] scanf ではバッファオーバーランを防げない
- [迷信] scanf でキーボードから入力
- [迷信] setjmp マクロの返却値は変数に代入できる
- [迷信] sizeof は定数式
- [迷信] void main(void)
- [迷信] とりあえず memset で初期化
- [迷信] アルゴリズム関数内で関数オブジェクトはコピーされない
- [迷信] オブジェクトの動的生成に失敗するとメモリリークする
- [迷信] コンストラクタから例外を送出してはならない
- [迷信] コンストラクタで自身をゼロクリア
- [迷信] コンパイラはプログラマの心を察してくれる
- [迷信] コンパイルエラーが出るのでアクセス指定子を修正
- [迷信] ソースコード中の即値を全廃せよ
- [迷信] ソースファイルの末尾に }
- [迷信] データ列のソートには qsort 関数を使うべし
- [迷信] プログラムは必ず main から始まる
- [迷信] 一重引用符の中には一文字しか書けない
- [迷信] 今どき int が 16 ビットの処理系なんて無い
- [迷信] 入力データ格納用配列のサイズは BUFSIZ
- [迷信] 割付けたメモリはプログラマが自分で解放しなければならない
- [迷信] 実数型とは浮動小数点型のことである
- [迷信] 引用符で囲んだヘッダ名はカレントディレクトリから探索する
- [迷信] 文字列から整数への変換には atoi
- [迷信] 構造体のタグ名は下線で始める
- [迷信] 構造体はクラスではない
- [迷信] 識別子に使える文字は英数字と下線のみ
- [迷信] 非局所オブジェクトは外部結合
- C言語再入門
- C言語徹底入門
- Drupal メモ
- TOPPERS 情報
- ライブラリ開発入門
- 分割コンパイルをきわめる
- 擬似プロセッサを作る
- 車輪の再発明
- 過去の情報


一応補足として...
C++ だけでなく C でも、char, signed char, unsigned char の三つはそれぞれ別の型です。JIS X3010 からの引用でも、「三つの型char, signed char及びunsigned char...」と明記されていますね。