在 C++ 函数中,如果它正在为 64 位架构编译,我需要编译器选择不同的块。
我知道为 MSVC++ 和 g++ 做的一种方法,所以我会把它作为答案发布。但是我想知道是否有更好的方法(更优雅,适用于所有编译器/所有 64 位架构)。如果没有更好的方法,我应该寻找哪些其他预定义宏才能与其他编译器/架构兼容?
在 C++ 函数中,如果它正在为 64 位架构编译,我需要编译器选择不同的块。
我知道为 MSVC++ 和 g++ 做的一种方法,所以我会把它作为答案发布。但是我想知道是否有更好的方法(更优雅,适用于所有编译器/所有 64 位架构)。如果没有更好的方法,我应该寻找哪些其他预定义宏才能与其他编译器/架构兼容?
在 C 和 C++ 中检测 32 位和 64 位构建的独立于体系结构的方法如下所示:
// C
#include <stdint.h>
// C++
#include <cstdint>
#if INTPTR_MAX == INT64_MAX
// 64-bit
#elif INTPTR_MAX == INT32_MAX
// 32-bit
#else
#error Unknown pointer size or missing size macros!
#endif
这适用于 MSVC++ 和g++
:
#if defined(_M_X64) || defined(__amd64__)
// code...
#endif
你为什么选择一个街区而不是另一个街区?如果您的决定是基于指针的大小,请使用sizeof(void*) == 8
. 如果您的决定是基于整数的大小,请使用sizeof(int) == 8
.
我的观点是架构本身的名称应该很少有任何区别。你只检查你需要检查的,为了你要做的事情。您的问题并没有很清楚地说明您检查的目的是什么。您所问的类似于尝试通过查询 Windows 版本来确定是否安装了 DirectX。您可以使用更多可移植和通用的工具。
雷蒙德涵盖了这一点。
如果你正在为 Windows 平台编译,你应该使用:
#ifdef _WIN64
MSVC 编译器为 x64 和 ia64 平台定义了这一点(您不想切断这个市场,是吗?)。我不确定 gcc 是否也这样做 - 但如果没有,它应该这样做。
另一种选择是
#ifdef WIN64
这有一个微妙的区别。WIN64(不带前导下划线)由 SDK(或构建配置)定义。由于这是由 SDK/build 配置定义的,它应该与 gcc 一样工作。
#ifdef _LP64
适用于两个平台
这是 Mac OS X 的一个很好的概述:
http://developer.apple.com/documentation/Darwin/Conceptual/64bitPorting
如果您使用 Windows,最好从注册表中获取“PROCESSOR_ARCHITECTURE”环境变量,因为如果它是在 64 位操作系统(又名 WOW64)上运行的 32 位进程,则 sizeof(PVOID) 将等于 4:
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("SYSTEM\CurrentControlSet\\Control\\Session Manager\\Environment"), 0, KEY_READ, &hKey) == ERROR_SUCCESS) {
LPSTR szArch = new CHAR[100];
ZeroMemory(szArch, 100);
if (RegQueryValueEx(hKey, _T("PROCESSOR_ARCHITECTURE"), NULL, NULL, (LPBYTE)szArch, &dwSize) == ERROR_SUCCESS) {
if (strcmp(szArch, "AMD64") == 0)
this->nArchitecture = 64;
else
this->nArchitecture = 32;
} else {
this->nArchitecture = (sizeof(PVOID) == 4 ? 32 : 64);
}
RegCloseKey(hKey);
}