【问题标题】:Why sizeof built in types except char is compiler dependent in C & C++?为什么除了 char 之外的内置类型 sizeof 在 C 和 C++ 中依赖于编译器?
【发布时间】:2016-06-01 17:40:47
【问题描述】:

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

【问题讨论】:

  • 如果您认为char 已定义,那么您还没有读到CHAR_BIT...
  • 你确定 short 比 char 长吗?我认为保证它不会小于 char,很多链接int 永远不会smaller 比long。
  • @DietrichEpp:EOF 的评论显然是关于 OP 认为一个 char 等于一个字节意味着 char 始终具有相同的大小、范围和表示。
  • @FUZxxl 有 2 种语言是 C 和 C++,并且在这个问题上非常相似。一遍又一遍地重复相同的解雇commet而不考虑它是没有用的

标签: c++ c types


【解决方案1】:

整数数据类型没有严格指定,因此编译器可以选择对目标硬件最有效的类型。但是,每种类型的最小大小都有一些保证(例如,int 至少为 16 位)。

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

【讨论】:

    【解决方案2】:

    原因很大程度上是因为 C 可以移植到更多种类的平台上。有很多原因导致不同数据类型在不同平台上具有不同的大小,但至少从历史上看,int 已被调整为平台的原生字长。在 PDP-11 上它是 16 位的(long 最初是为 32 位数字发明的),而一些嵌入式平台编译器甚至有 8 位 ints。当 32 位平台出现并开始使用 32 位 ints 时,发明了 short 来表示 16 位数字。

    如今,大多数 64 位架构使用 32 位 ints 只是为了与最初为 32 位平台编写的大量 C 程序库兼容,但是已经有 64 位 C 编译器具有 64 -bit ints 也是如此,尤其是一些早期的 Cray 平台。

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

    此外,也许应该说char 没有定义为1 个字节,而是定义为sizeof 返回1 的任何内容。这不一定是8位。 (为了完整起见,也许应该在此处添加,“byte”作为一个术语并没有被普遍定义为 8 位;它的历史定义有很多,并且在 ANSI C 标准的上下文中, “字节”实际上定义为可以存储char 的最小存储单元,无论char 的性质如何。)

    还有运行 C 程序的 36 位 PDP-10 和 18 位 PDP-7 等架构。现在它们可能相当少见,但确实有助于解释为什么 C 数据类型不是以 8 位单位定义的。

    这最终是否真的让这种语言比像 Java 这样的语言“更便携”可能还有待商榷,但在 16 位处理器上运行 Java 程序肯定不是最理想的,而且在 36 位处理器上确实很奇怪——位处理器。公平地说,它使 语言 更便携,但用它编写的程序更不便携。

    编辑: 作为对一些 cmets 的回复,我只想补充一点,作为一种观点,C 作为一种语言不同于 Java/Haskell/ADA 之类的语言。 - 较少由公司或标准机构“拥有”。当然有 ANSI C,但 C 不仅仅是 ANSI C;这是一个活生生的社区,并且有许多不兼容 ANSI 但仍然是“C”的实现。争论使用 8 位 ints 的实现是否是 C 类似于争论 Scots 是否是英语,因为这几乎没有意义。他们使用 8 位 ints 是有充分理由的,没有足够了解 C 的人无法推理为此类编译器编写的程序,而为此类架构编写 C 程序的任何人都希望他们的 ints 为 8 位.

    【讨论】:

    • @Peter:查看 PDP-11/20 C 编译器的源代码,short 不是定义的关键字,而 long 是。此外,我一直在使用至少一个 8 位 ints 的 PIC C 编译器。您可能会争辩说它不符合标准,但它确实存在。
    • 感谢众神,我从来没有在任何微型计算机之前的机器上工作过,但我听说过战争故事。而这些盒子正是 C 最初的用途。
    • "而一些嵌入式平台编译器甚至有 8 位 ints。" - 这在几乎所有已标准化的 C 版本中都是公然非法的。这些编译器不能准确地称为“C 编译器”,因为它们不符合规范。
    • @Dolda2000:标准明确将char 定义为单个字节,不多也不少。只是一个字节可以大于一个octett(永远不会更小)。字节的大小由CHAR_BIT 给出。
    • @Dolda2000:该标准没有明确将一个字节定义为 8 位,因此除非您指的是其他内容,否则我不确定您的意思。
    【解决方案3】:

    效率是答案的一部分——例如,如果您在使用 36 位寄存器的机器上使用 C 或 C++,您不希望强制每个操作都包含开销以掩盖结果,以便它们看起来/表现得像 32 位。

    不过,这实际上只是答案的一部分。另一部分是 C 和 C++ 曾经(并且现在)旨在成为系统编程语言。您的目标是能够使用它们编写虚拟机和操作系统之类的东西。

    这意味着如果(例如)您正在编写将与这台 36 位机器上的 MMU 交互的代码,并且您需要设置某个特定字的第 34 位,那么 C 和 C++ 的基本意图是你应该可以直接用语言做到这一点。如果该语言一开始就规定不能存在 36 位类型,这通常会使该语言中直接操作 36 位类型变得困难。

    因此,C 和 C++ 的基本前提之一是,如果您需要做某事,您应该能够在语言内部 做这件事。 Java 中的相应前提几乎完全相反:它允许你做的事情应该限制在它可以保证安全且可移植到任何东西的那些操作上。

    特别要记住,当 Sun 设计 Java 时,他们想到的主要目标之一就是用于网页的小程序。他们特别打算将 Java 限制为最终用户可以运行任何 Java 小程序,并且知道它不可能损害他们的机器而感到安全。

    当然,情况已经发生了变化——他们所追求的安全性仍然难以捉摸,小程序基本上已经死了。尽管如此,大多数旨在支持该模型的限制仍然存在。

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

    当然,这也不是完成大致相同事情的唯一可能方法。例如,Ada 采取了一条不同的路线。不是将“本机”类型面向机器,然后添加具有保证属性的特殊类型,而是向另一个方向发展,并具有具有保证属性的本机类型,而且还提供了用于定义直接对应于的新类型的完整工具目标机器。然而,无论好坏,Ada 从未像 C、C++ 或 Java 那样广泛使用,而且它解决这个特定问题的方法似乎也没有被许多其他语言采用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-03-05
      • 1970-01-01
      • 2011-01-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多