【问题标题】:Char vs unsigned char for byte arrays字节数组的字符与无符号字符
【发布时间】:2012-12-11 11:52:35
【问题描述】:

当存储“字节数组”(blob...)时,最好使用charunsigned char 来存储项目(unsigned char 又名uint8_t)? (标准说两者的sizeof 正好是 1 个字节。)

这有关系吗?还是一种比另一种更方便或更流行?也许,像 Boost 这样的库使用什么?

【问题讨论】:

标签: c++ gcc c++11


【解决方案1】:

如果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 @。

【讨论】:

    【解决方案2】:

    理论上,C++ 中一个字节的大小取决于编译器设置和目标平台,但保证至少为 8 位,这就解释了为什么sizeof(uint8_t) 必须为 1。

    以下是标准对它的更准确表述

    §1.71

    C++ 内存模型中的基本存储单元是字节。一种 字节至少足够大以包含基本的任何成员 执行字符集(2.3)和八位代码单元 Unicode UTF-8 编码形式,由一个连续的序列组成 位数,其数量由实现定义。至少 有效位称为低位;最高位 称为高位。 C++ 程序可用的内存 由一个或多个连续字节序列组成。每个字节都有 一个唯一的地址。

    因此,如果您正在处理一些字节不是 8 位的特殊硬件,它可能会产生实际的差异。否则,我会说这是一个品味问题,以及你想通过选择类型来传达什么信息。

    【讨论】:

      【解决方案3】:

      可能对 blob 使用有符号值的其他问题之一是该值将取决于符号表示,这不是标准的一部分。因此,调用未定义的行为更容易。

      例如...

      signed char x = 0x80;
      int y = 0xffff00ff;
      
      y |= (x << 8); // UB
      

      实际的算术值也将严格取决于二进制补码,这可能会给一些人带来惊喜。显式使用 unsigned 可以避免这些问题。

      【讨论】:

        【解决方案4】:

        没有实际区别,尽管从可读性的角度来看,如果类型是 unsigned char 意味着值 0..255 会更清楚。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2018-07-30
          • 2017-12-03
          • 2018-05-25
          • 2013-07-11
          • 1970-01-01
          • 2016-11-29
          • 1970-01-01
          • 2018-04-07
          相关资源
          最近更新 更多