C标准支持的平台列表

有没有人知道C标准支持的任何平台,仍然有积极的开发工作,但它们是:

  • 不是2的补充或
  • 整数宽度不是32位或64位或
  • 某些整数类型有填充位或
  • 如果您使用2的补码机器,符号位1和所有值位0的位模式不是有效的负数或
  • 从有符号到无符号的整数转换(反之亦然)不是通过逐字复制位模式或
  • 整数的右移不是算术移位或
  • 无符号类型中的值位数不是对应的有符号类型+ 1或中的值位数
  • 从较宽的int类型转换为较小的类型不是通过截断不适合的最左边的位

编辑:或者,如果在1995年至1998年期间有平台影响C99决定包括上述内容,但已经停止,我也会对它们感兴趣。

编辑:C理由有关填充位的说法:

填充位是用户可访问的无符号整数类型。 例如,假设一台机器使用一对16位短路(每个都有自己的符号位)来构成一个32位的int,并且当在这个32位int中使用时,忽略较低short的符号位。 然后,作为32位有符号整数,在确定32位有符号int的值时会忽略一个填充位(在32位的中间)。 但是,如果将此32位项目视为32位无符号整数,则该填充位对用户程序可见。 C委员会被告知有一台机器以这种方式工作,这就是填充位被添加到C99的一个原因。

脚注44和45提到奇偶校验位可能是填充位。 委员会不知道任何具有用户可访问的奇偶校验位的机器在整数内。 因此,委员会不知道任何将奇偶校验位视为填充位的机器。

所以另一个问题是,C99提到的那台机器是什么?

编辑:似乎C99正在考虑取消对1的补码和签名幅度的支持: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n868.htm http://www.open- std.org/jtc1/sc22/wg14/www/docs/n873.htm (搜索6.2.6.2)

我最近在一家仍在使用PDP-10版本的公司工作,并在该平台上使用了GCC端口。 我们使用的10个具有您列出的一些属性:

  • 整数不是32位或64位,它们是36位宽。
  • 填充位用于某些表示。 对于扩展精度整数(例如,长long类型),底层表示是72位,其中每个36位字具有符号位。

除了上述不寻常的属性之外,还存在机器具有多种不同的字节寻址机制的问题。 宽度在6-12位宽范围内的字节可以通过使用地址本身中的特殊位来解决,该位表示正在使用哪个宽度和字对齐。 为了表示char *,可以使用一个表示8位字节的表示,所有这些字节都在字中左对齐,在每个36位字中留下4位,根本没有被寻址。 或者,可以使用9位字节,它可以均匀地适合36位字。 这两种方法都存在可移植性方面的缺陷,但在我离开时,由于与TCP / IP网络和标准设备的交互,我认为使用8位字节更为实际,这些设备通常以16,24或32的forms进行思考-bit字段,也具有8位字节的底层结构。

据我所知,这个平台仍然在该领域的产品中使用,并且该公司的编译器开发人员保持最新版本的GCC最新版本,以便在该平台上进行进一步的C开发。

应该注意的是,即使在常用平台上也不能依赖未定义的行为,因为现代优化编译器执行的程序转换只保留定义的行为。

特别是,你不能依赖二进制补码算术给你INT_MAX+1 == INT_MIN 。 例如,gcc 4.6.0将以下内容优化为无限循环:

 #include  int main() { int i = 0; while (i++ >= 0) puts("."); return 0; } 

编辑 : 有关签名溢出和GCC优化的更多信息, 请参见此处 。

大约十年前,我们不得不将我们的C嵌入式数据库移植到一个恰好是汽车音响的主处理器的DSP处理器上。 它是一台24位机器,最糟糕的方式: sizeof(char) == sizeof(int) == sizeof(void*) == 1 ,这是24位。 我们将处理此端口的分支命名为“24位地狱”。

从那时起,我们将我们的库移植到许多平台上,但没有一个像我那样奇怪。 他们可能仍然在那里(便宜的24位DSP芯片现在甚至更便宜),在低成本设备中找到,其中易于编程远远低于材料清单(BOM)。 想想看,我认为我们确实遇到了一个机器,其中无符号整数的右移不必插入零位。 即便如此,平台上高度非标准的算术规则也能确保将软件移植到具有挑战性,容易出错的位置,从而大大增加了软件开发成本。 在某些时候,理智占上风,并且遵守标准。

我怀疑在C99中存在这些规则的很多动机是他们在C89中的存在,以及早期的语言迭代。 不要忘记,当C被发明时,计算机比现在更加多样化。 可以使用“位片”处理器设计,只需添加芯片就可以在处理器中添加任意数量的位。 在C之前,您必须使用汇编语言进行编码,或者担心代码将在RAM中的确切位置,等等。

C在可移植性方面迈出了一大步,但它必须包含各种各样的系统,因此是非常一般的规则。 20年后,当Java出现时,它有历史的好处,允许它预先声明原始类型的大小,这使得一切都变得容易,只要Java的选择是合理的。

我知道你主要是询问整数,但是在指针方面我遇到了一些奇怪的问题。 早期的Macintosh计算机有32位处理器(Motorola 68000),但只有24位内存总线。 因此,0x00123456和0xFF123456指的是相同的存储单元,因为处理器在访问RAM时会切断高8位。 Apple工程师使用这些位来存储有关指针所指向的内存的元数据。 因此,在比较指针时,必须首先屏蔽高位。 并且不要让我开始使用x86的分段内存架构 。 🙂

由于我们就这一主题,请看一下MISRA编码标准,该标准受到需要最大便携性和安全性的汽车制造商的青睐。 另请参阅 Henry S. Warren的Hacker’s Delight ,其中有大量有用的技巧。

我的两分钱。 请不要责怪,这是根据我的经验,我不是一个理论:

  • 不是2的补充

所有现有的CPU都是2的补码

  • 整数宽度不是32位或64位

还有8位和16位架构。 8位AVR MCU就是一个很好的例子。

  • 某些整数类型具有填充位

我不知道任何系统, 填充整数。 浮动数字 – 是一个不同的故事。

  • 如果您使用2的补码机器,则符号位1和所有值位0的位模式不是有效的负数
  • 从有符号到无符号的整数转换(反之亦然)不是通过逐字复制位模式
  • 整数的右移不是算术移位
  • 无符号类型中的值位数不是对应的有符号类型+ 1中的值位数
  • 从较宽的int类型转换为较小的类型不是通过截断不适合的最左边的位

以上所有 – 不知道任何,我认为没有这样的机器。

即使这些机器很古老,仍然有一个积极的PDP-8社区编程,大多数但并非全部使用模拟: PDP-8作为例子 。 而这台机器,AFAIK,使用12位整数!

Commodore C64的cc65编译器似乎在去年才有了一些更新。

一句古老的格言(我忘记了归属)说

没有可移植代码这样的东西

但只是有一些代码已被移植。

您不应该关心编写可移植代码,您应该关心编写易于移植到其他平台的代码。

此外,仅使用C标准不会给你带来太多有用的东西。 Posix标准为您提供更多。