在编译C或C++代码时,最可靠的查找CPU架构的方法是什么?据我所知,不同的编译器有自己的一套非标准预处理宏定义(如MSVS中的_M_X86
,GCC中的__i386__
、__arm__
等)。
是否有一个标准的方法来检测我正在构建的架构?如果没有,是否有一个包含各种编译器的所有这些定义的头文件,例如所有样板#ifdef
的综合列表的来源?
在编译C或C++代码时,最可靠的查找CPU架构的方法是什么?据我所知,不同的编译器有自己的一套非标准预处理宏定义(如MSVS中的_M_X86
,GCC中的__i386__
、__arm__
等)。
是否有一个标准的方法来检测我正在构建的架构?如果没有,是否有一个包含各种编译器的所有这些定义的头文件,例如所有样板#ifdef
的综合列表的来源?
请享用,我是这篇文章的原作者。
extern "C" {
const char *getBuild() { //Get current architecture, detectx nearly every architecture. Coded by Freak
#if defined(__x86_64__) || defined(_M_X64)
return "x86_64";
#elif defined(i386) || defined(__i386__) || defined(__i386) || defined(_M_IX86)
return "x86_32";
#elif defined(__ARM_ARCH_2__)
return "ARM2";
#elif defined(__ARM_ARCH_3__) || defined(__ARM_ARCH_3M__)
return "ARM3";
#elif defined(__ARM_ARCH_4T__) || defined(__TARGET_ARM_4T)
return "ARM4T";
#elif defined(__ARM_ARCH_5_) || defined(__ARM_ARCH_5E_)
return "ARM5"
#elif defined(__ARM_ARCH_6T2_) || defined(__ARM_ARCH_6T2_)
return "ARM6T2";
#elif defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__)
return "ARM6";
#elif defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7S__)
return "ARM7";
#elif defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7S__)
return "ARM7A";
#elif defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7S__)
return "ARM7R";
#elif defined(__ARM_ARCH_7M__)
return "ARM7M";
#elif defined(__ARM_ARCH_7S__)
return "ARM7S";
#elif defined(__aarch64__) || defined(_M_ARM64)
return "ARM64";
#elif defined(mips) || defined(__mips__) || defined(__mips)
return "MIPS";
#elif defined(__sh__)
return "SUPERH";
#elif defined(__powerpc) || defined(__powerpc__) || defined(__powerpc64__) || defined(__POWERPC__) || defined(__ppc__) || defined(__PPC__) || defined(_ARCH_PPC)
return "POWERPC";
#elif defined(__PPC64__) || defined(__ppc64__) || defined(_ARCH_PPC64)
return "POWERPC64";
#elif defined(__sparc__) || defined(__sparc)
return "SPARC";
#elif defined(__m68k__)
return "M68K";
#else
return "UNKNOWN";
#endif
}
}
每个编译器都没有标准,但每个编译器往往都非常一致。您可以为自己构建一个标题,例如:
#if MSVC
#ifdef _M_X86
#define ARCH_X86
#endif
#endif
#if GCC
#ifdef __i386__
#define ARCH_X86
#endif
#endif
因为有成千上万种编译器,但只有3-4个广泛使用(Microsoft C++、GCC、Intel CC,或许还有TenDRA?),所以全面的列表意义不大。只需决定哪些编译器适合您的应用程序,列出它们的#define,并根据需要更新头文件即可。
_M_X86
未被定义为正数(32位版本)。正确的是_M_IX86
(感谢上面Serge的链接)。 - Thomas如果您想在特定平台上卸载所有可用的功能,您可以运行以下命令:
gcc -march=native -dM -E - </dev/null
它会导出像 #define __SSE3__ 1
,#define __AES__ 1
等宏定义。
-xc++
开关来指定你正在编译的语言类型(C还是C++)。 - not2qubitBoost.Predef
,其中包含以下内容:
BOOST_ARCH_
:正在编译的系统/CPU架构。BOOST_COMP_
:正在使用的编译器。BOOST_LANG_
:正在编译的语言标准。BOOST_LIB_C_
和BOOST_LIB_STD_
:正在使用的C和C++标准库。BOOST_OS_
:我们正在编译的操作系统。BOOST_PLAT_
:基于操作系统或编译器的平台。BOOST_ENDIAN_
:操作系统和架构组合的字节序。BOOST_HW_
:硬件特定功能。BOOST_HW_SIMD
:检测SIMD(单指令多数据)。Boost.Predef
是纯头文件,也适用于C。#include <boost/predef.h>
// or just include the necessary headers
// #include <boost/predef/architecture.h>
// #include <boost/predef/other.h>
#if BOOST_ARCH_X86
#if BOOST_ARCH_X86_64
std::cout << "x86-64\n";
#elif BOOST_ARCH_X86_32
std::cout << "x86-32\n";
#else
std::cout << "x86-" << BOOST_ARCH_WORD_BITS << '\n'; // Probably x86-16
#endif
#elif BOOST_ARCH_ARM
#if BOOST_ARCH_ARM >= BOOST_VERSION_NUMBER(8, 0, 0)
#if BOOST_ARCH_WORD_BITS == 64
std::cout << "ARMv8+ Aarch64\n";
#elif BOOST_ARCH_WORD_BITS == 32
std::cout << "ARMv8+ Aarch32\n";
#else
std::cout << "Unexpected ARMv8+ " << BOOST_ARCH_WORD_BITS << "bit\n";
#endif
#elif BOOST_ARCH_ARM >= BOOST_VERSION_NUMBER(7, 0, 0)
std::cout << "ARMv7 (ARM32)\n";
#elif BOOST_ARCH_ARM >= BOOST_VERSION_NUMBER(6, 0, 0)
std::cout << "ARMv6 (ARM32)\n";
#else
std::cout << "ARMv5 or older\n";
#endif
#elif BOOST_ARCH_MIPS
#if BOOST_ARCH_WORD_BITS == 64
std::cout << "MIPS64\n";
#else
std::cout << "MIPS32\n";
#endif
#elif BOOST_ARCH_PPC_64
std::cout << "PPC64\n";
#elif BOOST_ARCH_PPC
std::cout << "PPC32\n";
#else
std::cout << "Unknown " << BOOST_ARCH_WORD_BITS << "-bit arch\n";
#endif
你可以在这里了解如何使用它
_M_ARM
只在32位ARM上定义? - Aaron FrankeBOOST_ARCH_WORD_BITS
轻松检查 ARM32。 - phuclv没有标准。Brian Hook在他的“可携带开源工具”中记录了其中许多内容,并尝试将它们变成一些连贯和可用的东西(关于这一点可能因人而异)。请参见此站点上的posh.h标头:
请注意,由于以前的DOS攻击,上面的链接可能需要您输入一些虚假的用户ID /密码。
这里有一个 #define
列表 在这里。之前有一个高票回答包含了这个链接,但是被版主删除了,可能是因为 SO 的“回答必须有代码”的规定。所以这里提供一个随机样本。点击链接查看完整列表。
类型 | 宏定义 | 描述 |
---|---|---|
识别 | __amd64__ __amd64 __x86_64__ __x86_64 |
由 GNU C 和 Sun Studio 定义 |
识别 | _M_X64 _M_AMD64 |
由 Visual Studio 定义 |
AMD64
和 Intel x86
宏的组合。但你几乎肯定不应该这样做。相反,应该使用 sizeof()
、static_assert
等等。此外,你应该了解 x32 ABI。即使在 64 位架构上,指针也可以是 32 位的。 - Timmmm