【问题标题】:int8_t vs char ; Which is the best one?int8_t 与 char ;哪个是最好的?
【发布时间】:2013-07-18 15:06:00
【问题描述】:

我知道两者是不同的类型(signed charchar),但是我公司的编码指南指定使用 int8_t 而不是 char

所以,我想知道,为什么我必须使用int8_t 而不是char 类型。有没有使用int8_t的最佳实践?

【问题讨论】:

  • 如果我没记错的话,char 不能保证正好是 8 位,它恰好是在大多数现代系统上。
  • int8_t 与平台无关,请参阅编译器中的 stdint.h 文件。
  • @JoachimPileborg 保证char 是一个字节长度。因此,char 中的位数取决于特定系统的字节数。
  • @suspectus:学究式地,对于定义它的任何平台。有些平台不支持 8 位类型。
  • 您不应该问问贵公司的其他人这些准则背后的基本原理是什么吗?

标签: c++ c char


【解决方案1】:

int8_t 的使用在某些情况下非常有用 - 特别是当该类型用于需要有符号 8 位值的计算时。涉及严格大小数据的计算[例如由外部要求定义为结果中的 8 位](我在上面的评论中使用了像素颜色级别,但实际上是uint8_t,因为负像素颜色通常不存在 - 可能在 YUV 类型的颜色空间中除外) .

int8_t 类型不应用作字符串中 char 的替代品。这可能导致编译器错误(或警告,但我们也不想处理来自编译器的警告)。例如:

int8_t *x = "Hello, World!\n";

printf(x);

可能在编译器 A 上编译得很好,但在编译器 B 上混合有符号和无符号字符值时会给出错误或警告。或者如果 int8_t 甚至没有使用 char 类型。这就像期待

int *ptr = "Foo";

在现代编译器中编译...

换句话说,如果您使用 8 位数据进行计算,则应该使用 int8_t 而不是 char。将所有char 全部替换为int8_t 是不正确的,因为它们远不能保证相同。

如果需要将char 用于字符串/文本/等,并且由于某种原因char 太模糊(可以签名或未签名等),则使用typedef char mychar; 或类似的东西应该使用。 (或许能找到比mychar更好的名字!)

编辑:我应该指出,无论你是否同意这一点,我认为简单地走到公司负责这一“原则”的人面前,指着关于 SO 的帖子和说“我认为你错了”。尝试了解动机是什么。它可能比看起来更多。

【讨论】:

  • 我会反对你的第二句话。首先,由于积分提升,all 计算将在int 或更大范围内进行。因此,您无疑是指必须在尽可能少的空间中存储小的有符号值。为此,signed char 可能更可取。您应该在代码中看到int8_t 的唯一情况是类型必须匹配某些外部协议或硬件。 (像素可能应该是uint24_t,每种颜色有 8 位,但通常不存在。)
  • 以后:如果char是16位,那么int8_t将不存在。它必须是可寻址类型(不是位字段),并且char 必须是最小的可寻址类型(当然,在该 C/C++ 实现中支持:某些机器,例如 VAX,支持寻址单个位)。
  • 很好地描述了我的问题,谢谢 Mats Peterson。
  • @JamesKanze 好的,我已经为您的 cmets 进行了修改。我确实认为我的信息的本质很清楚:char 不是int8_t 的替代品,反之亦然 - 它们不应该互换使用。
  • 谢谢你的回答,我明白了,我对“mychar”的首选名称是“ascii_t”,这是个好名字吗?
【解决方案2】:

他们只是做出不同的保证:

char 保证存在,至少为 8 位宽,并且能够表示 -127 到 127 之间(如果有符号)或 0 到 255(如果无符号)之间的所有整数。

int8_t 不保证存在(是的,有些平台不存在),但如果存在,则保证为 8 位二进制补码有符号整数类型,没有填充位;因此它能够表示 -128 到 127 之间的所有整数,仅此而已。

什么时候应该使用哪个?当类型做出的保证符合您的要求时。然而值得注意的是,标准库的大部分都需要char * 参数,因此完全避免char 似乎是短视的,除非有意避免使用这些库函数。

【讨论】:

  • 谁保证补码?请参考?
  • 7.20.1.1 精确宽度整数类型,第 1 段:“typedef 名称 intN_t 指定宽度为 N、无填充位、和二进制补码表示的有符号整数类型 。” (强调我的)。
  • @GrijeshChauhan:是的,在 C 中,“字节”被定义为“char 的大小”,char 被定义为最小的可寻址内存单元。存在一些架构(主要是 DSP),其中最小的可寻址内存单元是 16、24 甚至 32 位。
  • 如果您的公司告诉您将int8_t 用于实际上是char 值的东西,例如在字符串中,是的。如果您使用int8_t 是因为您想要一个小整数来执行计算(例如像素颜色值),那么int8_t 是非常正确的做法。请注意,尽管在您的平台上使用 int8_t *x = "Hello, World!\n"; printf(x); 可以很好地编译,但在另一个平台上可能无法正常工作。
  • @GrijeshChauhan 至少有一个相对现代的平台,其中字节为 9 位(而signed char 是 1 的补码);它一个 C++ 编译器。而且我听说在某些嵌入式平台上,字节是 16 位或 32 位。
【解决方案3】:

int8_t适用于需要恰好 8 位宽的有符号整数类型的代码,如果没有此类类型,则不应编译。这样的要求比关于int8_t 的问题数量要少得多,而且它的兄弟们指出。对大小的大多数要求是该类型至少具有特定数量的位。如果您需要至少 8 位,signed char 工作得很好; int_least8_t 也可以。

【讨论】:

    【解决方案4】:

    int8_t 由 C99 标准指定为正好 8 位宽,并且适合其他 C99 保证宽度类型。您应该在需要精确 8 位有符号整数的新代码中使用它。 (不过也可以看看int_least8_tint_fast8_t。)

    char 仍然首选作为单字节字符串的元素类型,就像wchar_t 应该首选作为宽字符串的元素类型一样。

    【讨论】:

    • stdint.h 对所有基本类型都有 typedef,为什么没有为 'char' 定义它?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-29
    • 1970-01-01
    • 2011-07-03
    相关资源
    最近更新 更多