4

我有一个从某个网站复制的示例程序。

int main(void)
{
   int answer;
   short x = 1;
   long y = 2;
   float u = 3.0;
   double v = 4.4;
   long double w = 5.54;
   char c = 'p';

   typedef enum
   {
      kAttributeInvalid,
      kBooleanAttributeActive,
      kBooleanAttributeAlarmSignal,
      kBooleanAttributeAlign64,
      kBooleanAttributeAutoNegotiationComplete,
   }codes_t;

  /* __DATE__, __TIME__, __FILE__, __LINE__ are predefined symbols */
  #if 0
  printf("Date : %s\n", __DATE__);
  printf("Time : %s\n", __TIME__);
  printf("File : %s\n", __FILE__);
  printf("Line : %d\n", __LINE__);
  #endif

  /* The size of various types */
  printf("The size of int         %zu\n", sizeof(answer));
  printf("The size of short       %zu\n", sizeof(x));
  printf("The size of long        %zu\n", sizeof(y));
  printf("The size of float       %zu\n", sizeof(u));
  printf("The size of double      %zu\n", sizeof(v));
  printf("The size of long double %zu\n", sizeof(w));
  printf("The size of char        %zu\n", sizeof(c));
  printf("The size of enum        %zu\n", sizeof(codes_t));

  return 0;
}

我运行了这个程序,得到的输出如下。

The size of int         4
The size of short       2
The size of long        8
The size of float       4
The size of double      8
The size of long double 16
The size of char        1
The size of enum        4

我在运行 64 位 Ubuntu 的 linux PC 上运行它。我的问题是,如果我要在 32 位机器上运行相同的程序,我会看到不同的结果。或者换句话说,基本数据的大小类型取决于

  1. 处理器
  2. 操作系统
  3. 还要别的吗
4

5 回答 5

7

我的问题是,如果我要在 32 位机器上运行相同的程序,我会看到不同的结果吗

也许。或者可能不是。

或者换句话说,基本数据类型的大小是否取决于 1) 处理器 2) 操作系统 3) 其他任何东西

  1. 是的,2. 是的,3. 是的,例如,如果您在 64 位操作系统上以 32 位兼容模式运行 32 位应用程序,那么它很可能会使用 32 位字长(当然,它是这样编译的)。哦,是的,它也可能取决于编译器。

“还有你的编译器标志......”(谢谢,凯!)

于 2013-02-11T22:06:21.057 回答
4

如果您关心变量的确切大小,请使用

#include <stdint.h>

然后使用那里定义的固定宽度类型:

uint8_t
uint16_t
uint32_t
uint64_t

或他们签名的表亲

int8_t
int16_t
int32_t
int64_t

不要依赖 C 中本机类型的大小。不同的编译器有不同的规则。

于 2013-02-11T22:09:05.670 回答
4

如果必须在它的 32 位变体中安装一些库 [可能只是 glibc],您应该可以使用gcc -m32 myprog.c[or clang -m32 myprog.c] 自己尝试一下。

但是,如果您使用基于 gcc 的编译器从 64 位 x86 linux 系统迁移到 32 位 x86 linux 系统,列出的项目中唯一会发生变化的是long. 请注意 x86、gcc 等的严格限定——编译器有很大的自由度。有人可以为 Linux 编写一个编译器,在 32 位系统上使用 16 位int和 64 位,没有太大的困难。long使用该编译器编译 Linux 内核和许多 Linux 工具可能会失败 [很可能包括gcc使用该编译器进行编译]。但是你不能真的说“在这个架构上”或“在这个操作系统中”或“使用这个编译器”......而不限定其他参数是什么。

恰当的例子:long即使在 64 位系统上,Microsoft C/C++ 编译器也有 32 位的。为什么,我听到你问?long因为当 Windows 是 Intel 286/386 处理器上的 16 位操作系统时,大量 Windows API 函数用作 32 位值作为遗留值。由于(某些)系统调用在 Windows 中向后兼容很长一段时间,为 16 位系统编写的代码仍然可以在 64 位 Windows 上工作 [除非代码使用一些非常不寻常的系统调用,当然, STYLE 会显得有点古旧]。更改long为 64 位值会破坏某些功能,因此 MS 的编译器人员决定坚持使用long= 32 位。如果你想要 64 位整数,你必须使用long longorint64_t或其他东西,而不是long. 当然,这会破坏一些假定sizeof(long) == sizeof(void *). 希望大多数这样的代码已经被修复......

于 2013-02-11T22:32:34.933 回答
2

是的,在某些情况下,它取决于硬件、操作系统、编译器甚至语言。

但是在 x86 linux 上,long 在 32 位平台上将是 4 个字节,而不是 8 个。我相信其他的都保持不变(不确定 long double)。

轶事:

我在一个字长为 24 位的 24 位系统上工作过,每个本机类型的大小为 1 个字。大小(字符)?1(即:24 位)。大小(整数)?1(即:24 位)。等有趣!

于 2013-02-11T22:08:11.803 回答
2

大小由编译器在编译时固定设置,因为编译器必须发出特定于大小的指令,在结构中布置成员,并知道所有需要的地址计算的结构大小。

因此,如果您将源代码编译为 64 位二进制文​​件并在一堆不同的系统上运行,如果系统完全支持二进制文件,则每次运行时类型将具有相同的大小。

如果您随后将源代码编译为 32 位二进制文​​件或使用不同的编译器开关,当您在一堆不同的系统上运行它时,数字可能与 64 位的情况不同,但它们在所有不同的情况下都是一致的系统。

于 2013-02-11T22:18:36.690 回答