编译C或C ++代码时找出CPU体系结构的最可靠方法是什么?据我所知,不同的编译器有自己的一组非标准预处理器定义(_M_X86
在MSVS中__i386__
,__arm__
在GCC中等)。
有没有检测我要构建的体系结构的标准方法?如果不是,是否有针对各种编译器的此类定义的完整列表的来源,例如带有所有样板文件的标头#ifdef
?
Answers:
没有内部编译器标准,但是每个编译器都趋于一致。您可以为自己构建标题,如下所示:
#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?)。只需确定您的应用程序将支持哪些编译器,列出其#defines并根据需要更新标头即可。
_M_X86
肯定没有定义(32位版本)。正确的是_M_IX86
(贷记至上面Serge的链接)。
如果您需要交叉编译器解决方案,则只需使用Boost.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(单指令多数据)检测。例如
#if defined(BOOST_ARCH_X86)
#if BOOST_ARCH_X86_64
std::cout << "x86_64 " << BOOST_ARCH_X86_64 << " \n";
#elif BOOST_ARCH_X86_32
std::cout << "x86 " << BOOST_ARCH_X86_32 << " \n";
#endif
#elif defined(BOOST_ARCH_ARM)
#if _M_ARM
std::cout << "ARM " << _M_ARM << " \n";
#elif _M_ARM64
std::cout << "ARM64 " << _M_ARM64 << " \n";
#endif
#endif
没有标准。布赖恩·胡克(Brian Hook)在他的“便携式开源线束”中记录了其中的许多内容,甚至试图使它们成为连贯且可用的东西(关于这个问题的ymmv)。请参阅此网站上的posh.h标头:
注意,由于DOS攻击前一段时间,上面的链接可能需要您输入一些虚假的用户ID /密码。
如果需要对CPU功能进行细粒度的检测,最好的方法是还附带一个将CPU支持的功能集输出到stdout或某些“ cpu_config.h”文件的CPUID程序。然后,您将该程序与构建过程集成在一起。