Joe*_*ery 127 c++ conditional-compilation 32bit-64bit
我正在寻找一种方法可靠地确定C++代码是在32位还是64位编译.我们已经提出了我们认为使用宏的合理解决方案,但很想知道人们是否可以想到这可能会失败的情况,或者是否有更好的方法来做到这一点.请注意,我们正在尝试在跨平台的多编译器环境中执行此操作.
#if ((ULONG_MAX) == (UINT_MAX))
# define IS32BIT
#else
# define IS64BIT
#endif
#ifdef IS64BIT
DoMy64BitOperation()
#else
DoMy32BitOperation()
#endif
Run Code Online (Sandbox Code Playgroud)
谢谢.
Kir*_*sky 99
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;
}
Run Code Online (Sandbox Code Playgroud)
Jar*_*Par 96
不幸的是,没有跨平台宏在主要编译器中定义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
Run Code Online (Sandbox Code Playgroud)
另一种更简单的方法是简单地从编译器命令行设置这些变量.
Con*_*ngo 43
不幸的是,在跨平台,交叉编译环境中,没有一种可靠的方法可以在编译时完全实现这一点.
因此,唯一可靠的方法是结合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
Run Code Online (Sandbox Code Playgroud)
在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
Run Code Online (Sandbox Code Playgroud)
一般规则是"每个#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
Run Code Online (Sandbox Code Playgroud)
评论来自@AI.G:
4年后(不知道以前是否可能)你可以使用static assert将运行时检查转换为编译时检查:static_assert(sizeof(void*)== 4);. 现在它都是在编译时完成的:)
从本质上讲,上述规则可以进行调整,使您的整个代码库更加可靠:
这种方法效果很好的原因在于它会强制您提前考虑每一个案例,而不是依赖于"else"部分中的(有时是有缺陷的)逻辑来执行正确的代码.
我使用这种技术(以及许多其他技术)编写了一个30,000行项目,从最初部署到生产的那一天起就完美无缺(那是12个月前).
ale*_*gle 28
您应该能够使用中定义的宏stdint.h.特别INTPTR_MAX是您需要的价值.
#include <cstdint>
#if INTPTR_MAX == INT32_MAX
#define THIS_IS_32_BIT_ENVIRONMENT
#elif INTPTR_MAX == INT64_MAX
#define THIS_IS_64_BIT_ENVIRONMENT
#else
#error "Environment not 32 or 64-bit."
#endif
Run Code Online (Sandbox Code Playgroud)
微软编译器的某些(所有?)版本没有附带stdint.h.不知道为什么,因为它是一个标准文件.这是您可以使用的版本:http://msinttypes.googlecode.com/svn/trunk/stdint.h
mat*_*ort 15
这在Windows上不起作用.无论您是编译32位还是64位窗口,长整数和整数都是32位.我认为检查指针的大小是否是8字节可能是一个更可靠的路由.
小智 8
你可以这样做:
#if __WORDSIZE == 64
char *size = "64bits";
#else
char *size = "32bits";
#endif
Run Code Online (Sandbox Code Playgroud)
小智 6
Try this:
#ifdef _WIN64
// 64 bit code
#elif _WIN32
// 32 bit code
#else
if(sizeof(void*)==4)
// 32 bit code
else
// 64 bit code
#endif
Run Code Online (Sandbox Code Playgroud)
下面的代码适用于大多数当前环境:
#if defined(__LP64__) || defined(_WIN64) || (defined(__x86_64__) && !defined(__ILP32__) ) || defined(_M_X64) || defined(__ia64) || defined (_M_IA64) || defined(__aarch64__) || defined(__powerpc64__)
#define IS64BIT 1
#else
#define IS32BIT 1
#endif
Run Code Online (Sandbox Code Playgroud)