【问题标题】:Why is the sizeof(int) == sizeof(long)?为什么 sizeof(int) == sizeof(long)?
【发布时间】:2013-09-24 21:58:36
【问题描述】:

在下面列出的程序中,sizeof(int) 和 sizeof(long) 在我的机器上是相等的(都等于 4 字节(或 32 位))。据我所知,long 是 8 个字节。它是否正确?我有一台 64 位机器

#include <stdio.h>
#include <limits.h>

int main(void){
    printf("sizeof(short) = %d\n", (int)sizeof(short));
    printf("sizeof(int) = %d\n", (int)sizeof(int));
    printf("sizeof(long) = %d\n", (int)sizeof(long));
    printf("sizeof(float) = %d\n", (int)sizeof(float));
    printf("sizeof(double) = %d\n", (int)sizeof(double));
    printf("sizeof(long double) = %d\n", (int)sizeof(long double));
    return 0;
}

【问题讨论】:

  • this
  • 我认为您的代码输出回答了您的问题。
  • @CharlieBurns 好吧,代码示例并不符合标准,因为编译器可能不兼容,可能具有特定于实现的行为或可能具有扩展。所以代码中的示例并不能证明它应该是什么。
  • @ShafikYaghmour 他的问题没有提到任何关于标准的内容。他的问题是'据我所知,长是 8 个字节。它是否正确?'从他的代码中可以明显看出答案是“不,你的机器上的 long 和你的编译器是 4 个字节”。

标签: c int long-integer sizeof


【解决方案1】:

据我所知,long 是 8 个字节。这是正确的吗?

不,这是不正确的。 C 和 C++ 规范仅规定 long 必须大于或等于 32 位。 int 可以更小,但在许多平台上,在 C 和 C++ 中,longint 都是 32 位。

这是prefer fixed width integer types 的一个很好的理由,例如int64_t,如果它们可供您使用并且您使用的是 C99 或为您提供等效类型的框架。

【讨论】:

  • sizeof(long) 在我非常典型的 64b 机器上是 8 个字节,所以我发现“在大多数机器上”很难接受。
  • @cnicular:一台机器既不是 C 实现,也不能确定 long 在针对该机器的 C 实现中的大小。您的意思是 sizeof(long) 在您非常典型的 C 实现中是 8 个字节吗?
  • @cnicutar 谁说“在大多数机器上”?即使在 64 位机器上,long 的大小也取决于编译器及其选项。在我的 64 位机器上,4 个编译器中有 4 个默认 sizeof(long) 为 4。一个编译器允许大小为 8。
  • 这就是为什么我使用“平台”而不是机器 - 按平台,我指定机器 + 它是运行时。
  • @chux 原始答案包含类似“典型”之类的内容 - 这就是我的评论获得投票的原因。最初的答案只提到了 C++,没有提到 C。很高兴看到它在此期间有所改进 :-)
【解决方案2】:

这取决于您的 ABI。如果您使用的是 Windows,Microsoft 选择了 LLP64 模型,因此 longint 都是 32 位,而 long long 和指针在 64 位构建中是 64 位,出于遗留原因。

大多数 UNIX 平台都选择了 LP64 模型,这使得 int 32 位、longlong long 和指针 64 位,用于 64 位构建。

但是,正如 Reed Copsey 所指出的,该标准仅规定了最小长度和相对长度。并且long必须大于等于int的长度。

【讨论】:

    【解决方案3】:

    C 不是 Java 也不是 C#。正如其他人所写,C 规范规定了最小长度和相对长度。为什么? C 被设计为低级的,几乎可以在任何硬件上编译和运行。

    如果一个规范对程序员的承诺太多,当硬件不支持这样的事情时,它的实现可能会变得很棘手(而且很慢)。 Java 和 C# 开发人员并不太在意,他们喜欢他们的语言对高级工作的便利性,并且会毫不犹豫地安装大型虚拟机来实现所有承诺(或至少大部分承诺)。

    C 程序员希望即使在机器指令级别也能控制代码。完全控制硬件。只有这样才能使用所有硬件功能,并达到最高性能。但是您必须小心您对所使用硬件的假设。与往常一样,权力越大,责任越大。

    只是为了说明:C 不假定 8 位字节。在&lt;limits.h&gt; 中查看CHAR_BIT

    一个相关的问题是Size of an integer in C

    【讨论】:

    • C 标准的某些方面确实没有很好地老化。标准类型的标头改进了一些东西,但据我所知,没有什么可以真正说明是否例如无符号“至少 8 位”类型和有符号“精确 16 位”类型之间的比较将是有符号或无符号的。可以对小于 32 位的事物进行操作但比对较大类型的操作慢的实现可能对前一种类型使用 32 位变量,对后者使用 16 位变量。我认为体型较大的类型不可能有较小的排名,因此......
    • ...我认为在“至少 8 位”类型大于“正好 16 位”类型的平台上,它的排名也必须更高,这意味着比较必须作为无符号进行。为特定大小的类型设置 typedef,而不指定有符号和无符号值如何交互,这似乎是灾难的根源。如果要设计一种新语言,可以区分用于保存应该包装的东西的无符号值和用于保存数字的无符号值。然后可以指定...的总和...
    • ...一个包装物和一个数字将是一个包装物与原始尺寸相同(如果数字更大,可能会发出警告),而总和如果存在这样的东西,两个数字将是一个足够大的类型来保存结果。包装事物和数字之间的比较需要将一个转换为另一个,并且将指定有符号和无符号值之间的比较在算术上是正确的。这样的规则将在很大程度上消除类型排名很重要的情况。不幸的是,它们与现有的 C 不兼容。
    【解决方案4】:

    不,标准定义了long 的最小值是4 bytesint2 bytes。根据C99 draft standard 部分5.2.4.2.1 整数类型的大小 段落1 说:

    [...]它们的实现定义值的大小应等于或大于[...]

    对于long,我们有:

     LONG_MIN -2147483647 // -(2^31 - 1)
     LONG_MAX +2147483647 // 2^31 - 1     
    

    这是4 bytes。为了完整起见,我们为int 提供以下内容:

     INT_MIN -32767 // -(2^15 - 1)
     INT_MAX +32767 // 2^15 - 1
    

    这是2 bytes

    【讨论】:

    • 不,类型以bits的数量指定。 C 对bytes 只字未提,只提及构成每种类型的最小位数。这不仅仅是学究气,因为在你检查之前你不知道CHAR_BIT 会是什么。
    • @TobySpeight:C 说了很多关于字节的很多。但是整数类型的最小所需大小没有定义为位或字节;它们被定义为值的范围。 int 的范围至少为 -32767 到 +32767。我们可以从范围推断它的大小至少为 16 位,我们可以从范围和CHAR_BIT 的值推断它需要多少字节(在填充位上涂上光泽),但两者都没有直接指定。
    • longint 完全有可能都是 1 字节大小(但前提是 CHAR_BIT &gt;= 32)。
    • @Keith,你的最后一条评论比我更简洁地表达了这个答案的问题 - 如果CHAR_BIT 足够大,任何类型的大小都可能为 1(这不是未知的;DSP 通常缺少小类型的寻址)。
    猜你喜欢
    • 2012-06-14
    • 1970-01-01
    • 2013-12-05
    • 2011-03-07
    • 2021-12-04
    • 2014-08-13
    • 1970-01-01
    • 2021-05-12
    相关资源
    最近更新 更多