【问题标题】:32-bit or 64-bit? Using C code32 位还是 64 位?使用 C 代码
【发布时间】:2011-04-20 02:36:17
【问题描述】:

有没有办法通过在 C 中编写一些代码来确定机器是 32 位还是 64 位?

【问题讨论】:

  • 你知道这个at compile time,不是吗?
  • 什么?没有36位机?还是128位?甚至是 8 位??
  • +1 @pmg。我也在相当多的 16 位和 24 位机器上工作过。
  • @GSerg:我在某处读到这个问题是一个潜在的问题,可以在面试中提出。

标签: c


【解决方案1】:
#include <limits.h>
/* ... */
printf("This machine's pointers to void, in a program "
       "compiled with the same options as this one and "
       "with the same compiler, use %d bits\n",
    (int)sizeof (void*) * CHAR_BIT);

【讨论】:

  • 完全没用。为 32 位平台编译您的程序并在 64 位机器上运行它。它永远不会知道机器是 64 位的。
  • 最重要的是,在典型的 16 位 C 平台上,指针很容易具有 32 位大小。
  • @AndreyT - 同样,当我在 Steem 下运行 Atari ST 程序或在 Vice64 下运行 C64 程序时,它永远不知道它在 PC 上运行。这就是仿真和虚拟机应该实现的目标。但这是一个相关点吗?有 32 位代码和 64 位代码,它们是不同的。目标代码中指针的宽度很可能是相关的。
  • @AndreyT:你说得对,谢谢。 printf 虽然没有改变
  • 真正的问题是他为什么想知道。如果他在 32 位机器上编译但在 64 位机器上运行,他可能很想知道他的代码是使用 32 位指针运行的;那么它不是没用的。
【解决方案2】:

如果“C 中的某些代码”是指标准 C 代码,那么答案是否定的,这是不可能的。对于 C 程序,它可以看到的“世界”完全由实现(由编译器)创建。编译器可以完全模拟任何“世界”,与底层硬件完全无关。

例如,您可以在 64 位机器上运行 32 位编译器,但您永远无法从您的程序中检测到这是一台 64 位机器这一事实。

您可以了解有关机器的任何信息的唯一方法是访问一些非标准设施,例如某些特定于操作系统的 API。但这远远超出了 C 语言的范围。

不用补充,其他答案中已经建议的基于sizeof 和其他标准语言工具的方法甚至无法检测机器的位数。相反,它们会检测编译器实现提供的平台的位数,这通常是完全不同的事情。

【讨论】:

  • +1 表示正确性;然而,这个“世界”的属性显然很重要,因为它们直接影响程序的执行,并且可能是 zero4 正在寻找的;我的水晶球在那个上不清楚;)
  • @Christoph - 我最近将水晶球从 32 位转换为 64 位。馊主意。把我的脚切成碎片,在碎片上上下跳动,最后得到了数百个比特——我想这解释了为什么它仍然不能正常工作。那好吧。仍然 - 我期待着“升级”我的电脑,只要我的脚痊愈。
  • @AndreyT - 有一些 API 会告诉您正在运行的 O/S 版本以及它的配置方式。它们不在 C 标准中,并且是特定于平台的,但这并不意味着 C 程序不能使用它们。为什么要检测它才是真正的问题 - 加载 32 位或 64 位主实现的 32 位引导程序可能有意义,但可能比每次都更有意义你运行它。
  • @Steve314:但这正是我的回答所说的:您不能在标准 C 中做到这一点,而只能通过特定于操作系统的 API。
  • @AndreyT - 标准 C 能够调用非标准库和 API。 C 中没有规则说“标准 C 编译器只能包含标准头文件”或“标准 C 兼容的链接器只能链接到标准库”,也没有“非标准库链接到标准C 代码也必须用标准 C" 编写。这是一个幼稚的迂腐观点,但根据我的经验,任何分歧都会导致技术细节的争吵,我永远不会承认我如此专注于评论的后半部分,以至于我没有检查前半部分。呃……哎呀!
【解决方案3】:

指针大小

sizeof (void *) * CHAR_BIT

是一个很好的指标,但可能会在更奇特的架构上产生误导(例如,如果地址总线的大小不是字长的倍数)并且仅代表执行环境(可能与实际硬件不同 - 请参阅AndreyT's answer)。

在预处理阶段,你可以在 C 语言框架内做的最好的事情是这样的

UINTPTR_MAX == UINT64_MAX

适用与上述相同的限制。

【讨论】:

    【解决方案4】:

    是的,如果在 x86 处理器上运行,请使用 CPUID 指令:

    http://en.wikipedia.org/wiki/CPUID

    【讨论】:

    • 你打算如何从 C 中做到这一点?
    • 可能通过将指向字符串的指针转换为函数指针并尝试调用它... ;-)
    • “你将如何从“C”中做到这一点?”:如果使用 Visual Studio:“__cpuid(b,a)”
    【解决方案5】:

    没有 32 位或 64 位环境之类的东西,这过于简单化了。如果你想编写一个可移植的应用程序,你有几个整数、指针和浮点大小的特性会发挥作用。

    您的不同整数类型的大小可以使用适当的宏来检查,例如UINT_MAX 等,指针大小通过UINTPTR_MAX。由于可能存在填充位,因此要推断类型的宽度,您应该打印类似 (unsigned long long)(T)-1 的内容,其中 T 是无符号类型。

    【讨论】:

      猜你喜欢
      • 2014-07-31
      • 2015-04-16
      • 1970-01-01
      • 2012-03-17
      • 1970-01-01
      • 1970-01-01
      • 2016-02-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多