什么平台有8位字符以外的东西?

Cra*_*een 133 c c++ cross-platform

不时有人在SO上指出char(也就是"字节")不一定是8位.

似乎8位char几乎是通用的.我原本认为,对于主流平台,必须有一个8位char才能确保其在市场上的可行性.

现在和历史上,哪些平台使用的char不是8位,为什么它们与"普通"8位不同?

在编写代码时,考虑跨平台支持(例如,对于通用库而言),对于非8位平台,值得考虑的是什么char

在过去,我遇到过一些char16位的ADI DSP .我认为DSP是一种利基架构.(然后,当时手工编写的汇编程序很容易击败可用的C编译器可以做的事情,所以我在该平台上没有真正获得C的经验.)

Ste*_*sop 77

char is also 16 bit on the Texas Instruments C54x DSPs, which turned up for example in OMAP2. There are other DSPs out there with 16 and 32 bit char. I think I even heard about a 24-bit DSP, but I can't remember what, so maybe I imagined it.

Another consideration is that POSIX mandates CHAR_BIT == 8. So if you're using POSIX you can assume it. If someone later needs to port your code to a near-implementation of POSIX, that just so happens to have the functions you use but a different size char, that's their bad luck.

但总的来说,我认为解决这个问题几乎总是比思考它更容易.只需输入CHAR_BIT.如果你想要一个精确的8位类型,请使用int8_t.你的代码将无法在没有提供代码的实现上编译,而不是默默地使用你没想到的大小.至少,如果我遇到一个我有充分理由认为它的情况,那么我就断言它.

  • 许多用于音频处理的DSP都是24位机器; 来自On Semi的[BelaSigna](http://www.onsemi.com/PowerSolutions/parametrics.do?id=2210)DSP(购买AMI Semi之后); 来自飞思卡尔的[DSP56K/Symphony Audio](http://www.freescale.com/webapp/sps/site/homepage.jsp?code=563XXGPDSP&tid=prodlib)DSP(从摩托罗拉分离出来之后). (7认同)
  • 而不是`assert()`(如果这就是你的意思),我会使用`#if CHAR_BIT!= 8` ...`#error"我需要CHAR_BIT == 8"````#endif` (4认同)
  • TI C62xx和C64xx DSP也具有16位字符.(uint8_t未在该平台上定义.) (2认同)
  • @msemack C64xx具有8/16/32/40的硬件和8位字符 (2认同)
  • @KeithThompson 有什么理由不使用 `static_assert()` 吗? (2认同)
  • @Qix:便携性。IIRC `static_assert` 仅在 2011 年添加到 C 标准中。 (2认同)

Joh*_*lla 36

在编写代码并考虑跨平台支持时(例如对于通用库而言),对于具有非8位字符的平台,值得考虑的是什么?

并不是因为规则所扮演的东西"值得考虑".例如,在C++中,标准规定所有字节都将具有"至少"8位.如果您的代码假设字节恰好是8位,则表示您违反了标准.

这看起来似乎很愚蠢 - " 当然所有字节都有8位!",我听到你说.但是许多非常聪明的人依赖于不是保证的假设,然后一切都破裂了.历史充满了这样的例子.

例如,大多数早期的90年代开发人员认为,采用固定数量的周期的特定无操作CPU定时延迟将花费固定的时钟时间,因为大多数消费者CPU的功率大致相等.不幸的是,计算机变得非常快.这产生了带有"Turbo"按钮的盒子的兴起 - 具有讽刺意味的是,它的目的是减慢计算机速度,以便使用延时技术的游戏可以以合理的速度播放.


一位评论者询问标准中的哪个字母表示char必须至少有8位.它在5.2.4.2.1节中.本节定义CHAR_BIT了最小可寻址实体中的位数,默认值为8.它还说:

它们的实现定义值的大小(绝对值)应等于或大于显示的值,并带有相同的符号.

所以任何等于8或更高的数字都适合用于实现的替换CHAR_BIT.

  • @Mark Ransom:这就是重点.开发人员通常依赖于目前看似真实的假设,但这些假设比最初出现时更加不稳定.(无法计算我犯错误的次数!)Turbo按钮应该是一个痛苦的提醒,不要做出不必要的假设,当然也不要做出语言标准无法保证的假设,就好像它们是不可改变的事实. (26认同)
  • 我至少在20年内没有看过涡轮按钮 - 你真的觉得它与这个问题密切相关吗? (6认同)
  • 第18.2.2节为其调用C标准.在C标准中,它是7.10节,然后是5.4.2.4.1节.C标准中的第22页. (5认同)
  • 您能否指出 C++ 标准中规定“再见”至少有 8 位的位置?这是一个普遍的信念,但我个人未能在标准中找到它。我在 Standard 中发现的唯一内容是哪些字符必须由 char 表示,其中字符数量超过 64 个,但少于 128 个,因此 7 位就足够了。 (2认同)
  • 因此,其他答案和评论都提到了具有5位,6位和7位字节的机器。这是否意味着您不能在符合标准的计算机上运行C程序? (2认同)
  • @JerryJeremiah:你可以在硬件数据单元小于8位的机器上运行C,但是一个C“字节”将是多个数据单元。您的物理指针的步长将小于一个字节,但 C 程序永远不会使用该粒度。(请注意,子字节数据不会有任何 C 数据类型) (2认同)

R S*_*hko 31

具有36位体系结构的计算机具有9位字节.据维基百科称,具有36位架构的机器包括:

  • 数字设备公司PDP-6/10
  • IBM 701/704/709/7090/7094
  • UNIVAC 1103/1103A/1105/1100/2200,

  • 我想,八进制实际使用的原因是因为3个八进制数字整齐地表示一个9位字节,就像我们今天通常使用十六进制一样,因为两个十六进制数字整齐地表示一个8位字节. (9认同)
  • 也是霍尼韦尔的机器,例如可能是实施C的第二台机器.参见K&R版本1. (6认同)
  • 实际上,Dec-10也有6位字符 - 你可以将其中的6个打包成36位字(前十二节程序员说话) (5认同)
  • 这个笑话实际上是为在这个架构上支持Unicode而实现的. (3认同)
  • DEC-20在TOPS-20 O/S上每36位字使用5个7位ASCII字符. (2认同)
  • PDP-6/PDP-10/DEC-10/DEC-20不仅具有6位字节,或7位字节,或8位字节或9位字节.它具有1到36位的任意字节大小. (2认同)

Jer*_*fin 18

其中一些我知道:

  • DEC PDP-10:变量,但最常见的是7位字符,每36位字包含5个字符,或者9位字符,每个字4个字符
  • 控制数据主机(CDC-6400,6500,6600,7600,Cyber​​ 170,Cyber​​ 176等)6位字符,每60位字包装10个.
  • Unisys主机:9位/字节
  • Windows CE:根本不支持`char`类型 - 需要16位wchar_t

  • Windows CE支持char,这是一个字节.请参阅Craig McQueen对Richard Pennington答案的评论.Windows CE中所需的字节数与其他地方一样多,无论其他地方的大小如何. (10认同)
  • Windows CE编译器真的不支持`char`类型吗?我知道系统库只支持带字符串的函数的宽字符版本,并且至少某些版本的WinCE删除了像strlen这样的ANSI字符串函数,以阻止你进行字符串处理.但它真的没有char类型吗?什么是`sizeof(TCHAR)`?malloc返回什么类型?Java`bytes`类型是如何实现的? (3认同)
  • C标准不允许每36位字填充5位7位字符(正如您在PDP-10中提到的那样),也不允许6位字符,就像您在控制数据大型机中提到的那样.请参阅http://www.parashift.com/c++-faq-lite/intrinsic-types.html#faq-26.6 (3认同)
  • @ephemient:我非常确定PDP-10/DecSystem 10/DecSystem 20至少有一个(预标准)C编译器.虽然我对*CDC大型机的C编译器感到非常惊讶(它们主要用于数字工作,所以Fortran编译器就是那里的大事.我很确定其他人都有C编译器. (2认同)
  • PDP-10有至少两种C实现:KCC和gcc端口(http://pdp10.nocrew.org/gcc/). (2认同)
  • @Jerry:顺便说一下,我并不是说你不能在那个硬件上实现一个C编译器,只是你必须使用不同的`char`大小来实现它. (2认同)

Ell*_*ioh 15

没有完全可移植的代码.:-)

是的,可能有各种字节/字符大小.是的,对于具有非常不寻常的值CHAR_BIT和的平台,可能存在C/C++实现UCHAR_MAX.是的,有时可以编写不依赖于字符大小的代码.

但是,几乎所有实际代码都不是独立的.例如,您可能正在编写将二进制消息发送到网络的代码(协议并不重要).您可以定义包含必要字段的结构.比你必须序列化它.只是将结构二进制复制到输出缓冲区是不可移植的:通常你不知道平台的字节顺序,也不知道结构成员对齐,所以结构只保存数据,但没有描述数据应该序列化的方式.

好.您可以执行字节顺序转换并将结构成员(例如uint32_t或类似)移动memcpy到缓冲区中.为什么memcpy?因为有很多平台在目标地址未正确对齐时无法写入32位(16位,64位 - 无差异).

所以,你已经做了很多工作来实现可移植性.

现在是最后一个问题.我们有一个缓冲区.来自它的数据被发送到TCP/IP网络.这种网络假定为8位字节.问题是:缓冲区应该是什么类型的?如果你的字符是9位?如果他们是16位?24?也许每个char对应一个发送到网络的8位字节,只使用8位?或者也许多个网络字节被打包成24/16/9位字符?这是一个问题,很难相信有一个适合所有情况的答案.很多事情都依赖于目标平台的套接字实现.

所以,我在说什么.通常,代码可以相对容易地在一定程度上便携.如果您希望在不同平台上使用代码,那么这样做非常重要.但是,提高超出该度量的可移植性需要付出很多努力并且通常很少,因为实际代码几乎总是依赖于其他代码(上例中的套接字实现).我确信,大约90%的代码能够在具有8位以外字节的平台上工作几乎是无用的,因为它使用绑定到8位的环境.只需检查字节大小并执行编译时断言.你几乎肯定会为一个非常不寻常的平台重写很多东西.

但如果您的代码高度"独立" - 为什么不呢?您可以以允许不同字节大小的方式编写它.

  • 如果每个'unsigned char`值存储一个八位字节,则应该没有可移植性问题,除非代码使用别名技巧而不是移位将八位字节序列转换为更大的整数类型.就个人而言,我认为C标准应该定义内部函数来从较短类型(最典型的是`char`)的序列中打包/解包整数,每个项目存储一个固定的保证可用位数(每个`unsigned char` 8个,每个`unsigned 16个) short`,或每个`unsigned long` 32. (4认同)

dmc*_*kee 9

您似乎仍然可以从仓库中购买IM6100(即芯片上的PDP-8).这是一个12位架构.


Alo*_*hal 9

许多DSP芯片具有16位或32位char.TI常规使得这样的芯片,例如.


pet*_*tik 5

例如,C和C++编程语言将字节定义为"足够大的可寻址数据单元,以容纳执行环境的基本字符集的任何成员"(C标准的第3.6节).由于C char整数数据类型必须至少包含8位(第5.2.4.2.1节),因此C中的一个字节至少能够保存256个不同的值.C和C++的各种实现将字节定义为8,9,16,32或36位

引自http://en.wikipedia.org/wiki/Byte#History

虽然不确定其他语言.

http://en.wikipedia.org/wiki/IBM_7030_Stretch#Data_Formats

将该计算机上的字节定义为可变长度