「バイト配列」(ブロブ...)を保存する場合、アイテム(別名)を使用する方が良いですchar
か?(標準では、両方とも正確に 1 バイトであると言われています。)unsigned char
unsigned char
uint8_t
sizeof
それはまったく問題ですか?それとも、一方が他方よりも便利または一般的ですか? たぶん、Boost のようなライブラリは何を使用していますか?
が符号付きの場合char
、上位ビットが設定されたバイト値で演算を実行すると、 に昇格するときに符号拡張が発生しint
ます。たとえば、次のようになります。
char c = '\xf0';
int res = (c << 24) | (c << 16) | (c << 8) | c;
0xfffffff0
の代わりにを与えます0xf0f0f0f0
。これは でマスキングすることで回避できます0xff
。
char
unsigned char
. _
char *
to/from からのキャストは常に安全であることに注意してくださいunsigned char *
(3.9p2)。支持する哲学的な理由unsigned char
は、少なくともオブジェクトのメモリ表現を保持できるバイト配列を表すために、標準の 3.9p4 がそれを支持していることです。
type のオブジェクトのオブジェクト表現は、 typeのオブジェクトによって取り上げられる
T
一連のオブジェクトです。ここで、equals です。N
unsigned char
T
N
sizeof(T)
理論的には、C++ の 1 バイトのサイズはコンパイラの設定とターゲット プラットフォームに依存しますが、少なくとも 8 ビットであることが保証されているためsizeof(uint8_t)
、 が 1 である必要がある理由が説明されています。
これは、標準がそれについて何を言わなければならないかをより正確に示しています
§1.71
C++ メモリ モデルの基本的な記憶単位はバイトです。バイトは少なくとも、基本実行文字セット (2.3) の任意のメンバーと Unicode UTF-8 エンコード形式の 8 ビット コード単位を格納するのに十分な大きさであり、ビットの連続シーケンスで構成され、その数は次のとおりです。実装定義。最下位ビットは下位ビットと呼ばれます。最上位ビットは上位ビットと呼ばれます。C++ プログラムで使用できるメモリは、1 つまたは複数の連続したバイト シーケンスで構成されます。すべてのバイトには固有のアドレスがあります。
そのため、バイトが 8 ビットではない特殊なハードウェアで作業している場合は、実質的な違いが生じる可能性があります。そうでなければ、それは好みの問題であり、タイプの選択を通じてどのような情報を伝えたいかということです.
ブロブに符号付きの値を潜在的に使用する場合のその他の問題の 1 つは、値が標準の一部ではない符号表現に依存することです。したがって、未定義の動作を呼び出す方が簡単です。
例えば...
signed char x = 0x80;
int y = 0xffff00ff;
y |= (x << 8); // UB
実際の算術値は 2 の補数にも厳密に依存するため、驚く人もいるかもしれません。unsigned を明示的に使用すると、これらの問題を回避できます。
実用的な違いはありませんが、読みやすさの観点からは、型がunsigned char
値 0..255 を暗示しているかどうかの方が明確です。