有没有一种标准的方法在编译时确定系统是32位还是64位?

7
我需要设置 #ifdef - 用于条件编译检查。我想要自动化这个过程,但无法指定目标操作系统/机器。预编译器是否有一种方式可以确定它是否在32位或64位上运行?
(解释)我需要定义一个大小为64位的类型。在64位操作系统上,它是long,在大多数其他操作系统上,它是long long。
我找到了这个答案 - 这是正确的方法吗?
[编辑]一个方便的编译器宏参考

3
你对64位系统的定义是什么?(这是一个严肃的问题) - NPE
为什么这对你的程序很重要? - lhf
4
所以您希望在32位机器上运行编译器时将代码编译为32位,或者在64位机器上运行编译器时将其编译为64位?我不太明白您的问题。此外,我觉得很难相信您无法指定目标操作系统/机器,特别是如果您是正在编译源代码的人。 - In silico
预编译器中没有关于目标系统“位数”的标准定义。您必须传递自己的定义,或者依赖于编译器本身定义的定义。例如:_WIN64 - Christopher
8个回答

10

您可以可靠地进行的唯一编译检查是 sizeof(void*) == 8,对于 x64 为真,对于 x86 为假。 这是一个constexpr,您可以将其传递给模板,但是不要忘记与之一起使用ifdef。没有平台无关的方法可以在预处理时知道目标体系结构的地址大小,您需要向IDE请求。标准甚至没有地址大小的概念。


关于模板的好建议,我认为那将是我们要走的路,也是最安全的。 - slashmais

4

在预处理阶段,宏无法确定计算机是64位还是32位,因此没有标准语言支持


4

针对您的编辑,有一种“无宏定义”的方法可以获取一个64位的类型。

如果您需要一个能够容纳64位的类型,则需要#include <cstdint>,然后使用int64_tuint64_t。您也可以使用Boost提供的标准整数类型

另一种选择是使用long long。虽然它在C++标准中并不被支持(将会在C++0x中支持),但它几乎被每个编译器所支持。


2
Boost已经吸收了旧的Predef项目。如果你只关心x86,你需要架构宏,更具体地说是BOOST_ARCH_X86_32/BOOST_ARCH_X86_64
如果你需要更广泛的检测(如ARM64),可以将相关宏添加到你的检测中,或者检查你实际想要检查的内容。
sizeof(void*) == 8

这就是仅有链接的答案存在的问题:链接已经失效,我不知道如何使用这个“答案”来解决我的问题。 - Violet Giraffe

2

我建议查看跨平台库的源代码。这是一个相当大的部分。每个操作系统和编译器的组合都有自己的一套定义。以下是几个值得注意的库:
http://www.libsdl.org/ \include\SDL_config*.h (几个文件)
http://qt.nokia.com/ \src\corelib\global\qglobal.h


1

嗯,答案显然会与操作系统有关,因此您需要缩小您的要求范围。

例如,在Unix上,uname -a通常提供足够的信息来区分32位操作系统构建和64位操作系统构建。

该命令可以被您的预处理器调用。根据其输出,可以适当地设置编译器标志。


那也不是编译时检查。 - Karoly Horvath
或者使用gcc -dM -E - < /dev/null命令中的符号。 - lhf

0

我会想把检测代码提取出来放到 Makefile 中。这样,你就可以利用系统工具来检测并设置适当的宏,以便在代码中进行切换。

在你的 Makefile 中...

<do stuff to detect and set SUPPORT_XX_BIT to the appropriate value>
gcc myFile.c -D$(SUPPORT_XX_BIT) -o myFile

你的代码中...
#if defined(SUPPORT_32_BIT)
...
#elif defined(SUPPORT_64_BIT)
...
#else
    #error "Select either 32 or 64 bit option\n"
#endif

-2

可能最简单的方法是比较 intlong long 的大小。虽然你不能在预处理器中这样做,但你可以在 static_assert 中使用它。

编辑:哇,所有的负评。我把我的观点表达得更清楚了。此外,由于 MSVC 的工作方式,我应该提到 'long long' 而不是 'long'。


你可能是指 INT_MAX 和 LONG_MAX 吗? - lhf
在 MSVC 上,64 位目标平台上的 int 和 long 都是 32 位。 - Puppy
@Oli:是的,我知道你不能在预处理器中使用sizeof。我更多地考虑了static_assert - AlefSin
@AlefSin:我的抱怨更多是基于intlong通常具有相同的大小。 - Oliver Charlesworth

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接