C标准支持的平台列表

时间:2011-11-04 10:24:29

标签: c standards

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

  • 不是2的补充或
  • 整数宽度不是32位或64位或
  • 某些整数类型有填充位或
  • 如果您使用2的补码机器,则带符号的位模式 位1和所有值位零不是有效的负数或
  • 从签名到无符号的整数转换(反之亦然)不是逐字逐句的 复制位模式或
  • 整数的右移不是算术移位或
  • 无符号类型中的值位数不是数量 相应的有符号类型+ 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)

8 个答案:

答案 0 :(得分:12)

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

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

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

编辑See here了解有关签名溢出和GCC优化的更多信息。

答案 1 :(得分:11)

大约十年前,我们不得不将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的segmented memory architectures。 :)

由于我们正在谈论这个话题,请看一下MISRA编码标准,这是需要最大便携性和安全性的汽车制造商所青睐的。另请参阅Henry S. Warren撰写的 Hacker's Delight ,其中有大量有用的技巧。

答案 2 :(得分:11)

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

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

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

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

答案 3 :(得分:6)

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

  • 不是2的补充

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

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

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

  • 某些整数类型有填充位

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

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

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

答案 4 :(得分:6)

即使这些机器很古老,仍然有一个活跃的PDP-8社区编程,大多数但不是全部使用模拟:PDP-8 as an example。 这台机器AFAIK使用12位整数!

答案 5 :(得分:4)

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

答案 6 :(得分:3)

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

  

没有便携式代码

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

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

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

答案 7 :(得分:0)

<块引用>

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

(几乎)所有平台都有一些既不是 32 也不是 64 位的整数。我想你的意思是 int ? 如果是这样,是的,有很多。有许多仍在生产中的微控制器具有 8 位,有时是 16 位内核。他们使用 16 位 int。对于电压力锅之类的东西来说,里面有一个 32 位处理器并没有多大意义。 PIC10、PIC12、PIC16 和 PIC18 以及 AVR 都不是 8 位的,其中许多仍在生产中。 在您提出这个问题 10 年后,今天仍然如此。

请不要假设 int 至少是 32 位,使用 uint_least32_tint_least32_tint_fast32_tuint_fast32_tuint32_tint32_tlongunsigned long。当我看到代码在 sizeof(int)*CHAR_BIT==16 时中断时,我很恼火。