为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

C++
料青山看我应如是 2019-10-15 14:35:40
我正在寻找一种可靠地确定C ++代码是否以32位和64位编译的方法。我们已经提出了我们认为使用宏的合理解决方案,但很想知道人们是否可以想到这种情况可能会失败,或者是否有更好的方法来做到这一点。请注意,我们正在尝试在跨平台的多编译器环境中执行此操作。#if ((ULONG_MAX) == (UINT_MAX))# define IS32BIT#else# define IS64BIT#endif#ifdef IS64BITDoMy64BitOperation()#elseDoMy32BitOperation()#endif谢谢。
查看完整描述

3 回答

?
繁花不似锦

TA贡献1851条经验 获得超4个赞

不幸的是,没有跨平台宏可以在主要编译器中定义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

另一个更简单的方法是从编译器命令行简单地设置这些变量。


查看完整回答
反对 回复 2019-10-15
?
qq_花开花谢_0

TA贡献1835条经验 获得超7个赞

template<int> void DoMyOperationHelper();


template<> void DoMyOperationHelper<4>() 

{

  // do 32-bits operations

}


template<> void DoMyOperationHelper<8>() 

{

  // do 64-bits operations

}


// helper function just to hide clumsy syntax

inline void DoMyOperation() { DoMyOperationHelper<sizeof(size_t)>(); }


int main()

{

  // appropriate function will be selected at compile time 

  DoMyOperation(); 


  return 0;

}


查看完整回答
反对 回复 2019-10-15
?
繁花如伊

TA贡献2012条经验 获得超12个赞

不幸的是,在跨平台,跨编译器的环境中,没有一种可靠的方法可以完全在编译时执行此操作。


如果项目设置有缺陷或损坏(特别是在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

   #if _WIN64

     #define ENV64BIT

  #else

    #define ENV32BIT

  #endif

#endif


// Check GCC

#if __GNUC__

  #if __x86_64__ || __ppc64__

    #define ENV64BIT

  #else

    #define ENV32BIT

  #endif

#endif

简单检查2/3:运行时检查

在main()中,仔细检查一下sizeof()是否有意义:


#if defined(ENV64BIT)

    if (sizeof(void*) != 8)

    {

        wprintf(L"ENV64BIT: Error: pointer should be 8 bytes. Exiting.");

        exit(0);

    }

    wprintf(L"Diagnostics: we are running in 64-bit mode.\n");

#elif defined (ENV32BIT)

    if (sizeof(void*) != 4)

    {

        wprintf(L"ENV32BIT: Error: pointer should be 4 bytes. Exiting.");

        exit(0);

    }

    wprintf(L"Diagnostics: we are running in 32-bit mode.\n");

#else

    #error "Must define either ENV32BIT or ENV64BIT".

#endif

简单检查3/3:强大的编译时间检查

一般规则是“每个#define必须以产生错误的#else结尾”。


#if defined(ENV64BIT)

    // 64-bit code here.

#elif defined (ENV32BIT)

    // 32-bit code here.

#else

    // INCREASE ROBUSTNESS. ALWAYS THROW AN ERROR ON THE ELSE.

    // - What if I made a typo and checked for ENV6BIT instead of ENV64BIT?

    // - What if both ENV64BIT and ENV32BIT are not defined?

    // - What if project is corrupted, and _WIN64 and _WIN32 are not defined?

    // - What if I didn't include the required header file?

    // - What if I checked for _WIN32 first instead of second?

    //   (in Windows, both are defined in 64-bit, so this will break codebase)

    // - What if the code has just been ported to a different OS?

    // - What if there is an unknown unknown, not mentioned in this list so far?

    // I'm only human, and the mistakes above would break the *entire* codebase.

    #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个月前)就一直完美无缺。


查看完整回答
反对 回复 2019-10-15
  • 3 回答
  • 0 关注
  • 514 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号