避免在平台独立代码中实现定义类型

Avoid implementation defined types in platform independent code

我刚开始从事一个应该独立于平台的大项目,但它实际上使用了实现定义的类型,例如 char

这已经造成了一些问题,因为对于某些设备 char 默认为 signed 而对于其他设备 unsigned.

我想找到一个解决方案,以避免在必须与平台无关的代码中使用实现定义的类型。

  1. 最好的解决方案是什么?使用编译器参数(例如:-funsigned-char)、typedefs 或其他参数将所有 char 变量重新定义为 unsigned char(或 signed char)?
  2. 是否还有其他类型,标准没有定义它们是有符号的还是无符号的?

经典的方法是使用您自己的 typedef 类型,让您的 make/autoconf 等检测平台特征并为您设置 typedef。

理论上,答案很简单:

始终按照预期目的使用类型。例如。您想要 实现定义的类型,例如数组的大小,因为在不同的平台上,这种大小的上限会有所不同。类似于指针。对于固定大小类型的需要,C 已经在 stdint.h.

中提供了适当的 typedefs

这是一个不完整的 "what-to-use" 列表:

  • 对不需要固定大小且永远不会超过 16 位范围的任何整数使用 (unsigned) int
  • 在处理将字符存储在 int.
  • 中的库函数时,char 用于字符,int 并强制转换为 unsigned char
  • 使用 size_t 表示任何与对象大小相关的内容,例如数组索引
  • 每当需要将指针的存储为整数
  • 时,请使用uintptr_t
  • 使用 intX_t/uintX_tX 是位数)用于您需要固定位数且不应根据目标更改的任何整数平台。
  • 如果类型的大小实际上是否更大并不重要,请改用 int_leastX_t/uint_leastX_t。无法解决八位字节的实现不会提供例如uint8_t,但它 提供 uint_least8_t 更多位。

对此有两种观点:

  1. 切勿使用 "plain" 类型,例如 intchar,因为您永远无法知道它们有多大。始终使用固定大小的类型,例如 <stdint.h>.
  2. 中定义的类型
  3. 尽可能使用 "plain" 类型,例如 intchar,因为它们应该始终与您机器上的本机类型相匹配。了解关于它们的保证和不保证的内容,以便您可以选择合适的——也就是说,有时您会想要 long int、或 unsigned int、或 size_t,或其他.在您绝对需要精确大小的类型的那些(希望很少)情况下,请使用 <stdint.h>.
  4. 中定义的类型

原来这是一个古老的问题,一直争论不休,没有一个统一的答案。