在C ++中确定32位和64位

我正在寻找一种可靠地确定C ++代码是否以32位和64位编译的方法。我们已经提出了我们认为使用宏的合理解决方案,但很想知道人们是否可以想到这种情况可能会失败,或者是否有更好的方法来做到这一点。请注意,我们正在尝试在跨平台的多编译器环境中执行此操作。


#if ((ULONG_MAX) == (UINT_MAX))

# define IS32BIT

#else

# define IS64BIT

#endif


#ifdef IS64BIT

DoMy64BitOperation()

#else

DoMy32BitOperation()

#endif

谢谢。


料青山看我应如是
浏览 515回答 3
3回答

繁花不似锦

不幸的是,没有跨平台宏可以在主要编译器中定义32/64位。我发现最有效的方法如下。首先,我选择自己的代表。我更喜欢ENVIRONMENT64 / ENVIRONMENT32。然后,我找出所有主要的编译器都使用什么来确定它是否是64位环境,然后使用它来设置我的变量。// Check windows#if _WIN32 || _WIN64#if _WIN64#define ENVIRONMENT64#else#define ENVIRONMENT32#endif#endif// Check GCC#if __GNUC__#if __x86_64__ || __ppc64__#define ENVIRONMENT64#else#define ENVIRONMENT32#endif#endif另一个更简单的方法是从编译器命令行简单地设置这些变量。

qq_花开花谢_0

template<int> void DoMyOperationHelper();template<> void DoMyOperationHelper<4>()&nbsp;{&nbsp; // do 32-bits operations}template<> void DoMyOperationHelper<8>()&nbsp;{&nbsp; // do 64-bits operations}// helper function just to hide clumsy syntaxinline void DoMyOperation() { DoMyOperationHelper<sizeof(size_t)>(); }int main(){&nbsp; // appropriate function will be selected at compile time&nbsp;&nbsp; DoMyOperation();&nbsp;&nbsp; return 0;}

繁花如伊

不幸的是,在跨平台,跨编译器的环境中,没有一种可靠的方法可以完全在编译时执行此操作。如果项目设置有缺陷或损坏(特别是在Visual Studio 2008 SP1上),则_WIN32和_WIN64有时都可能未定义。由于项目配置错误,标记为“ Win32”的项目可能设置为64位。在Visual Studio 2008 SP1上,根据当前的#define,有时intellisense不会使代码的正确部分变灰。这使得在编译时很难准确看到正在使用哪个#define。因此,唯一可靠的方法是结合3个简单的检查:1)编译时间设定,以及;2)运行时检查;以及;3)强大的编译时间检查。简单检查1/3:编译时间设置选择任何方法来设置所需的#define变量。我建议使用@JaredPar中的方法:// Check windows#if _WIN32 || _WIN64&nbsp; &nbsp;#if _WIN64&nbsp; &nbsp; &nbsp;#define ENV64BIT&nbsp; #else&nbsp; &nbsp; #define ENV32BIT&nbsp; #endif#endif// Check GCC#if __GNUC__&nbsp; #if __x86_64__ || __ppc64__&nbsp; &nbsp; #define ENV64BIT&nbsp; #else&nbsp; &nbsp; #define ENV32BIT&nbsp; #endif#endif简单检查2/3:运行时检查在main()中,仔细检查一下sizeof()是否有意义:#if defined(ENV64BIT)&nbsp; &nbsp; if (sizeof(void*) != 8)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; wprintf(L"ENV64BIT: Error: pointer should be 8 bytes. Exiting.");&nbsp; &nbsp; &nbsp; &nbsp; exit(0);&nbsp; &nbsp; }&nbsp; &nbsp; wprintf(L"Diagnostics: we are running in 64-bit mode.\n");#elif defined (ENV32BIT)&nbsp; &nbsp; if (sizeof(void*) != 4)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; wprintf(L"ENV32BIT: Error: pointer should be 4 bytes. Exiting.");&nbsp; &nbsp; &nbsp; &nbsp; exit(0);&nbsp; &nbsp; }&nbsp; &nbsp; wprintf(L"Diagnostics: we are running in 32-bit mode.\n");#else&nbsp; &nbsp; #error "Must define either ENV32BIT or ENV64BIT".#endif简单检查3/3:强大的编译时间检查一般规则是“每个#define必须以产生错误的#else结尾”。#if defined(ENV64BIT)&nbsp; &nbsp; // 64-bit code here.#elif defined (ENV32BIT)&nbsp; &nbsp; // 32-bit code here.#else&nbsp; &nbsp; // INCREASE ROBUSTNESS. ALWAYS THROW AN ERROR ON THE ELSE.&nbsp; &nbsp; // - What if I made a typo and checked for ENV6BIT instead of ENV64BIT?&nbsp; &nbsp; // - What if both ENV64BIT and ENV32BIT are not defined?&nbsp; &nbsp; // - What if project is corrupted, and _WIN64 and _WIN32 are not defined?&nbsp; &nbsp; // - What if I didn't include the required header file?&nbsp; &nbsp; // - What if I checked for _WIN32 first instead of second?&nbsp; &nbsp; //&nbsp; &nbsp;(in Windows, both are defined in 64-bit, so this will break codebase)&nbsp; &nbsp; // - What if the code has just been ported to a different OS?&nbsp; &nbsp; // - What if there is an unknown unknown, not mentioned in this list so far?&nbsp; &nbsp; // I'm only human, and the mistakes above would break the *entire* codebase.&nbsp; &nbsp; #error "Must define either ENV32BIT or ENV64BIT"#endif更新2017-01-17来自的评论@AI.G:4年后(不知道之前是否可能),您可以使用静态断言将运行时检查转换为编译时检查:static_assert(sizeof(void *)== 4);。现在,一切都在编译时完成了:)附录A偶然地,上述规则可以进行调整以使您的整个代码库更可靠:每个if()语句均以“ else”结尾,该警告会生成警告或错误。每个switch()语句均以“ default:”结尾,该警告会生成警告或错误。之所以如此有效,是因为它迫使您提前考虑每种情况,而不是依靠“其他”部分中的(有时是有缺陷的)逻辑来执行正确的代码。我使用了这项技术(以及其他许多技术)来编写一个30,000行的项目,该项目从首次部署到生产的那天(即12个月前)就一直完美无缺。
打开App,查看更多内容
随时随地看视频慕课网APP