可移植代码 - 每个字符的位数

33
我知道C/C++标准只保证每个字符的最低位数为8位,理论上9/16/42/其他任何位数都是可能的。因此,在编写可移植代码的相关网站中,所有人都会警告不要假设有8位每字符(char)。我的问题是这种情况有多“不可移植”呢?
让我解释一下。在我的看法中,有三类系统:
  1. 计算机 - 我指的是运行Mac/Linux/Windows/Unix/*nix/posix/任何其他操作系统的台式机、笔记本电脑、服务器等。我会很惊讶地听到任何这样的系统中char不恰好是8位的情况。(如果我错了,请纠正我)
  2. 带操作系统的设备 - 包括智能手机和诸如嵌入式系统之类的设备。虽然我不会对发现一个char超过8位的系统感到非常惊讶,但我目前还没有听说过这样的情况。(请再通知我一声)
  3. 裸机设备 - VCR、微波炉、旧手机等。在这个领域我没有任何经验,所以这里可能会出现任何情况。但是,我真的需要在我的Windows桌面和微波炉之间交叉使用我的代码吗?我有可能有共同的代码吗?
结果:在上述1和2类平台中,是否存在常见(超过0.001%)的情况,使得char不是8位?并且,我的上述推断是真的吗?

10
sizeof(char)始终为1。它的大小不是以比特为单位,而是以字符为单位。 - Baruch
2
不,这是类型的大小(以字节为单位),可以由此推导出位数。 - tbert
4
POSIX 要求 char 的位数为 8 位。然而,一些广泛使用的 DSP 具有 16 或 32 位的 char,例如许多 ARM 平台上使用的一些 TI DSP。你的智能手机上可能也有这样的芯片。 - ninjalj
2
你对裸机设备的评论似乎基于你计划编写的特定代码。你要求我们验证你的假设,却没有告诉我们它们的依据。例如,如果你编写低级别的计算库或数据传输代码,那么它可能会在未来的裸机设备上运行。但如果你编写GUI程序,则可能不行。 - David Schwartz
2
我认为这个问题激发了我花费数月时间研究和设计基于三进制的 C++ 分支,一个三进制汇编,以及一个三进制 CPU。https://xkcd.com/356/ - Mooing Duck
显示剩余10条评论
5个回答

29

22
我会建议这样做 :-) #如果 (CHAR_BIT!= 8) #错误 你很奇怪,请离开! #endif - Josh Petitt
2
我想知道是否可以编写代码,假设char是8位,而不是如何查找char中的位数。 - Baruch
1
@baruch,也许你在意吗?如果你想将32位打包到无符号整数中,并且你正在进行位操作或使用memcpy、memset等函数,则可能需要关注。因此,在这种情况下,请使用stdint.h类型。如果您要传递值给函数或执行其他只需使用本机int类型(或unsigned)的操作,则可能不需要关心。每当您确实非常关心时,我会在某个地方放置预处理器保护,以警告用户他们正在进入无人区,或通过提供两个不同的实现来解决问题。 - Josh Petitt
@baruch,序列化也是一个需要小心的领域。 - Josh Petitt
@baruch,对于这些问题,尽可能依赖你的编译器供应商和他们的标准实现。他们已经为您完成了大部分艰难的部分。而且,如果您关心一个字节中的位数,那么我不认为编写100%可移植的代码是可能的。在这种情况下,您可能需要编写两个实现来处理两者之间的任何差异。这比试图编写一些复杂混乱的代码要更容易,更快,更好,并且只有一半的代码将在给定平台上运行。 - Josh Petitt
显示剩余3条评论

6
例如,许多数字信号处理器(DSP)的CHAR_BIT大于或等于16。

1
这些不会落入我问题中的第三类吗? - Baruch
1
@baruch:并不是,其中许多都是作为更大系统的一部分,配备有“传统”的CPU和操作系统。 - ninjalj

4

至少在64位架构中,类似于整数大小一样,未来的平台可能会使用更宽的字符,带有更多的位。 ASCII字符可能会过时,被Unicode所取代。这可能是一个需要谨慎对待的原因。


1
这实际上是一个反例。为了不破坏所有依赖于int为32位的代码,我认为所有常见的编译器即使在64位系统上也将int保留为32位。 - Baruch
1
@baruch,我同意他们目前确实这样做,但是谁知道会持续多久。 - perreal

0

Posix标准要求CHAR_BIT为8。

因此,如果您只关心代码在Posix兼容平台上运行,则假设CHAR_BIT == 8是可以的。

绝大多数商品PC平台和构建系统都符合此要求。任何使用BSD套接字接口的平台很可能会隐含地具有此要求,因为假设平台字节是八位字节非常广泛分布。

#if CHAR_BIT != 8
#error Your platform is unsupported!
#endif

POSIX为什么规定CHAR_BIT==8?

只有当您希望代码在嵌入式和奇特的平台上运行时,才需要担心这种假设/约束。否则,在我看来,这是一个相当安全的假设。


0

通常情况下,可以安全地假设文件具有8位字节,或者如果不是这种情况,则可以通过常用工具将8位字节文件转换为零填充本机格式。但是,假定CHAR_BIT == 8则更加危险。目前几乎总是这种情况,但未来可能不再如此。 8位访问内存越来越成为瓶颈。


1
如果我们都假设CHAR_BIT等于8,那么未来的处理器将永远无法在市场上立足,因为当我们将程序编译到这些处理器时,我们的程序将无法工作。因此,CHAR_BIT将始终等于8。哈哈?(实际上,这让我感到非常沮丧) - Jack G

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接