【发布时间】:2012-12-11 11:52:35
【问题描述】:
当存储“字节数组”(blob...)时,最好使用char 或unsigned char 来存储项目(unsigned char 又名uint8_t)? (标准说两者的sizeof 正好是 1 个字节。)
这有关系吗?还是一种比另一种更方便或更流行?也许,像 Boost 这样的库使用什么?
【问题讨论】:
-
@nightcracker 也许,你能指出复制品吗?
当存储“字节数组”(blob...)时,最好使用char 或unsigned char 来存储项目(unsigned char 又名uint8_t)? (标准说两者的sizeof 正好是 1 个字节。)
这有关系吗?还是一种比另一种更方便或更流行?也许,像 Boost 这样的库使用什么?
【问题讨论】:
如果char 是有符号的,那么在提升到int 时,对设置了高位的字节值执行算术将导致符号扩展;所以,例如:
char c = '\xf0';
int res = (c << 24) | (c << 16) | (c << 8) | c;
将给出0xfffffff0 而不是0xf0f0f0f0。这可以通过使用0xff 屏蔽来避免。
如果您与使用它而不是unsigned char 的库进行交互,char 可能仍然更可取。
请注意,从char * 到/从unsigned char * 的转换始终是安全的 (3.9p2)。支持unsigned char 的一个哲学原因是标准中的 3.9p4 支持它,至少在表示可以保存对象内存表示的字节数组时:
T类型对象的对象表示是T类型对象占用的Nunsigned char对象序列,其中N等于@987654337 @。
【讨论】:
理论上,C++ 中一个字节的大小取决于编译器设置和目标平台,但保证至少为 8 位,这就解释了为什么sizeof(uint8_t) 必须为 1。
以下是标准对它的更准确表述
§1.71
C++ 内存模型中的基本存储单元是字节。一种 字节至少足够大以包含基本的任何成员 执行字符集(2.3)和八位代码单元 Unicode UTF-8 编码形式,由一个连续的序列组成 位数,其数量由实现定义。至少 有效位称为低位;最高位 称为高位。 C++ 程序可用的内存 由一个或多个连续字节序列组成。每个字节都有 一个唯一的地址。
因此,如果您正在处理一些字节不是 8 位的特殊硬件,它可能会产生实际的差异。否则,我会说这是一个品味问题,以及你想通过选择类型来传达什么信息。
【讨论】:
可能对 blob 使用有符号值的其他问题之一是该值将取决于符号表示,这不是标准的一部分。因此,调用未定义的行为更容易。
例如...
signed char x = 0x80;
int y = 0xffff00ff;
y |= (x << 8); // UB
实际的算术值也将严格取决于二进制补码,这可能会给一些人带来惊喜。显式使用 unsigned 可以避免这些问题。
【讨论】:
没有实际区别,尽管从可读性的角度来看,如果类型是 unsigned char 意味着值 0..255 会更清楚。
【讨论】: