除了char之外,为什么sizeof内置类型在C&C++中依赖于编译器?

Ccy*_*yan 25 c c++ types

为什么C和C++中的基本类型没有像Java那样严格定义,其中a int始终为4个字节且long为8个字节等.据我所知,在C和C++中,只有a char被定义为1个字节,其他所有内容都由不同的编译器定义不同.所以int在C和C++中,只要它长于a short并且short更长,就不一定必须是4个字节char.
我只是想知道为什么会这样,它有用吗?

Dol*_*000 33

原因很大程度上是因为C可以移植到更广泛的平台上.有很多原因可以解释为什么不同的数据类型已经证明了它们在各种平台上的各种大小,但至少在历史上,它int已经被改编为平台的原生单词大小.在PDP-11上它是16位(long最初发明用于32位数字),而一些嵌入式平台编译器甚至有8位数int.当32位平台出现并开始使用32位时int,short发明了代表16位数字.

如今,大多数64位架构使用32位int只是为了与最初为32位平台编写的大型C程序兼容,但也有64位C编译器和64位ints,其中一些早期的Cray平台.

此外,在计算的早期阶段,浮点格式和大小通常远没有标准化(IEEE 754直到1985年才出现),这就是为什么floats和doubles甚至不如整数数据类型定义的原因.他们通常甚至不假设存在诸如无穷大,NaN或有符号零的特殊性.

此外,或许应该说a char未定义为1个字节,而是为sizeof1返回1.这不一定是8位.(为了完整起见,也许应该在这里添加,作为术语的" 字节 "不是普遍定义为8位;已经有许多历史定义,并且在ANSI C标准的上下文中," "字节"实际上被定义为可以存储的最小存储单元char,无论其性质如何char.)

还有36位PDP-10和18位PDP-7这样的架构也运行C程序.它们现在可能非常罕见,但确实有助于解释为什么C数据类型没有按照8位单位定义.

最终是否真的使这种语言比Java这样的语言"更具可移植性"可能会引起争论,但在16位处理器上运行Java程序肯定不是最理想的,而在36位处理器上确实非常奇怪.可以公平地说,它使语言更具可移植性,但用它编写的程序不那么便携.

编辑:在回复一些评论时,我只想补充一下,作为一种观点,C作为一种语言不像Java/Haskell/ADA那样被公司或标准或多或少"拥有"的语言.身体.确实有ANSI C,但C大于ANSI C; 它是一个活生生的社区,有许多实现不兼容ANSI,但仍然是"C".争论使用8位ints的实现是否是C类似于争论苏格兰人是否是英语,因为它几乎没有意义.他们使用8位ints是有充分理由的,没有人知道C足够好就无法推断为这些编译器编写的程序,任何为这种架构编写C程序的人都希望他们的ints是8位.

  • "虽然一些嵌入式平台编译器甚至有8位`int`s." - 在几乎所有已经标准化的C版本中,这显然是非法的.那些编译器不能被准确地称为"C编译器",因为它们不符合规范. (15认同)
  • @Dolda2000:标准没有明确地将字节定义为8位,所以除非你指的是其他东西,否则我不确定你的意思. (5认同)
  • @Dolda2000:标准明确地将`char`定义为单​​个字节,不多也不少.它只是一个字节可以大于*octett*(从不小).以字节为单位的字节大小由`CHAR_BIT`给出. (3认同)
  • @Peter:看看PDP-11/20 C编译器的源代码,`short`不是定义的关键字,而`long`是.另外,我一直在使用至少一个带有8位`int`s的PIC C编译器.您可能会认为它不符合标准,但尽管如此,它仍然存在. (2认同)

Bud*_*ddy 23

未严格指定整数数据类型,以便编译器可以选择对目标硬件最有效的任何内容.但是,每种类型的最小尺寸都有一些保证(例如int,至少为16位).

查看此页面:http://en.cppreference.com/w/cpp/language/types


Jer*_*fin 10

效率是答案的一部分 - 例如,如果在使用36位寄存器的计算机上使用C或C++,则不希望强制每个操作都包含开销来屏蔽结果,使它们看起来像/像32一样位.

这真的只是答案的一部分.另一部分是C和C++是(并且)打算成为系统编程语言.您打算能够用它们编写虚拟机和操作系统之类的东西.

这意味着如果(例如)你正在编写将在这个36位机器上与MMU交互的代码,并且你需要设置某个特定单词的第34位,那么C和C++的基本意图就是你应该是能够直接用语言表达.如果语言通过判断首先不存在36位类型而开始,则通常难以直接操作该语言的36位类型.

所以,C和C++的基本前提之一是,如果你需要做的事情,你应该能够做到这一点的东西里面的语言.Java中相应的前提几乎正好相反:它允许你做的事情应该限制在它可以保证安全和可移植到任何东西的那些操作上.

特别要记住的是,当Sun设计Java时,他们想到的一个重要目标是网页applet.它们专门用于限制Java,使最终用户可以运行任何Java applet,并且知道它不可能损害他们的机器.

当然,情况已经发生了变化 - 他们所针对的安全性仍然难以实现,并且applet基本上已经死亡而且已经消失.尽管如此,旨在支持该模型的大多数限制仍然存在.

我应该补充一点,这不完全是一种或两种情况.有许多方法可以提供一些中间立场.C和C++标准的合理最近迭代包括那些类型int32_t.这保证了32位,2的补码表示,就像Java类型一样.因此,如果您在实际支持32位二进制补码类型的硬件上运行,int32_t则会出现并且您可以使用它.

当然,这也不是完成大致相同的事情的唯一可能方式.例如,阿达采取了一种不同的路线.而不是"本机"类型面向机器,然后添加具有保证属性的特殊类型,它走向另一个方向,并且具有保证属性的本机类型,而且还有用于定义直接对应的新类型的整个工具.目标机器.然而,无论好坏,Ada从未达到过与C,C++或Java一样广泛的用途,并且它对这个特定问题的处理方式似乎也没有被许多其他语言采用.