简体   繁体   English

如何检测我是否正在用 C++ 编译 64 位架构

[英]How can I detect if I'm compiling for a 64bits architecture in C++

In a C++ function I need the compiler to choose a different block if it is compiling for a 64 bit architecture.在 C++ 函数中,如果编译器为 64 位体系结构编译,我需要编译器选择不同的块。

I know a way to do it for MSVC++ and g++, so I'll post it as an answer.我知道一种针对 MSVC++ 和 g++ 执行此操作的方法,因此我会将其发布为答案。 However I would like to know if there is a better way (more elegant that would work for all compilers/all 64 bits architectures).但是我想知道是否有更好的方法(更优雅,适用于所有编译器/所有 64 位架构)。 If there is not a better way, what other predefined macros should I look for in order to be compatible with other compiler/architectures?如果没有更好的方法,为了与其他编译器/架构兼容,我应该寻找哪些其他预定义宏?

An architecture-independent way to detect 32-bit and 64-bit builds in C and C++ looks like this:在 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

This works for MSVC++ and g++ :这适用于 MSVC++ 和g++

#if defined(_M_X64) || defined(__amd64__)
  // code...
#endif

Why are you choosing one block over the other?你为什么选择一个街区而不是另一个街区? If your decision is based on the size of a pointer, use sizeof(void*) == 8 .如果您的决定是基于指针的大小,请使用sizeof(void*) == 8 If your decision is based on the size of an integer, use sizeof(int) == 8 .如果您的决定基于整数的大小,请使用sizeof(int) == 8

My point is that the name of the architecture itself should rarely make any difference.我的观点是架构本身的名称应该很少有任何区别。 You check only what you need to check, for the purposes of what you are going to do.你只检查你需要检查的东西,为了你将要做的事情。 Your question does not cover very clearly what your purpose of the check is.你的问题没有很清楚地说明你检查的目的是什么。 What you are asking is akin to trying to determine if DirectX is installed by querying the version of Windows.您所问的问题类似于尝试通过查询 Windows 版本来确定是否安装了 DirectX。 You have more portable and generic tools at your disposal.您可以使用更多可移植和通用的工具。

雷蒙德涵盖了这一点

If you're compiling for the Windows platform, you should use:如果您正在为 Windows 平台编译,则应使用:

#ifdef _WIN64

The MSVC compiler defines that for both x64 and ia64 platforms (you don't want to cut out that market, do you?). MSVC 编译器为 x64 和 ia64 平台定义了这一点(您不想切断那个市场,是吗?)。 I'm not sure if gcc does the same - but it should if it doesn't.我不确定 gcc 是否也这样做 - 但如果没有,它应该这样做。

An alternative is另一种选择是

#ifdef WIN64

which has a subtle difference.这有一个微妙的区别。 WIN64 (without the leading underscore) is defined by the SDK (or the build configuration). WIN64(不带前导下划线)由 SDK(或构建配置)定义。 Since this is defined by the SDK/build config, it should work just as well with gcc.由于这是由 SDK/build 配置定义的,因此它应该与 gcc 一样好。

#ifdef _LP64

适用于两个平台

If your using Windows, your probably better to get the "PROCESSOR_ARCHITECTURE" environment variable from the registry because sizeof(PVOID) will equal 4 if its a 32bit process running on a 64bit operating system (aka WOW64):如果您使用的是 Windows,则最好从注册表中获取“PROCESSOR_ARCHITECTURE”环境变量,因为如果它的 32 位进程在 64 位操作系统(又名 WOW64)上运行,则 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);
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM