本文对分别测试VC,MinGW,GCC 三种编译器,32位和64位模式,共6种情况下,和64位编程有关的与预定义宏的值。对跨平台编程具有参考意义。
Agner Fog 在他的《Calling conventions for different C++ compilers and operating systems》提到一些预订宏。这里摘录如下。
注:下面的内容来自《Calling conventions for different C++ compilers and operating systems》,Last updated 2012-02-29,作者:By Agner Fog. Copenhagen University College .如何原文内容不符,以原文为准。
Most C++ compilers have a predefined macro containing the version number of the
compiler. Programmers can use preprocessing directives to check for the existence of these
macros in order to detect which compiler the program is compiled on and thereby fix
problems with incompatible compilers.
Table 23. Compiler version predefined macros
Compiler | Predefined macro |
Borland | __BORLANDC__ |
Codeplay VectorC | __VECTORC__ |
Digital Mars | __DMC__ |
Gnu | __GNUC__ |
Intel | __INTEL_COMPILER |
Microsoft | _MSC_VER |
Pathscale | __PATHSCALE__ |
Symantec | __SYMANTECC__ |
Watcom | __WATCOMC__ |
Unfortunately, not all compilers have well-documented macros telling which hardware
platform and operating system they are compiling for. The following macros may or may not
be defined:
Table 24. Hardware platform predefined macros
platform | Predefined macro | ||
x86 | _M_IX86 | __INTEL__ | __i386__ |
x86-64 | _M_X64 | __x86_64__ | __amd64 |
IA64 | __IA64__ |
|
|
DEC Alpha | __ALPHA__ |
|
|
Motorola Power PC | __POWERPC__ |
|
|
Any little endian | __LITTLE_ENDIAN__ |
|
|
Any big endian | __BIG_ENDIAN__ |
|
|
Table 25. Operating system predefined macros
Operating system | Predefined macro | |||
DOS 16 bit | __MSDOS__ | _MSDOS |
|
|
Windows 16 bit | _WIN16 |
|
|
|
Windows 32 bit | _WIN32 | __WINDOWS__ |
|
|
Windows 64 bit | _WIN64 | _WIN32 |
|
|
Linux 32 bit | __unix__ | __linux__ |
|
|
Linux 64 bit | __unix__ | __linux__ | __LP64__ | __amd64 |
BSD | __unix__ | __BSD__ | __FREEBSD__ |
|
Mac OS | __APPLE__ | __DARWIN__ | __MACH__ |
|
OS/2 | __OS2__ |
|
|
|
下面的代码主要测试和64编程有关的宏
void test()
{
int len=sizeof(int)*8;
printf("sizeof(int)=%d\n",len);
len=sizeof(int *)*8;
printf("sizeof(int*)=%d\n",len);
#ifdef _MSC_VER
printf("_MSC_VER is defined\n");
#endif
#ifdef __GNUC__
printf("__GNUC__ is defined\n");
#endif
#ifdef __INTEL__
printf("__INTEL__ is defined\n");
#endif
#ifdef __i386__
printf("__i386__ is defined\n");
#endif
#ifdef __x86_64__
printf("__x86_64__ is defined\n");
#endif
#ifdef _WIN32
printf("_WIN32 is defined\n");
#endif
#ifdef _WIN64
printf("_WIN64 is defined\n");
#endif
#ifdef __linux__
printf("__linux__ is defined\n");
#endif
#ifdef __LP64__
printf("__LP64__ is defined\n");
#endif
#ifdef __amd64
printf("__amd64 is defined\n");
#endif
}
int main(int argc, char* argv[])
{
test();
return 0;
}
最后给出结果.
1. 在VC2010, 32位模式下编译,输出下面的信息
sizeof(int)=32
sizeof(int*)=32
_MSC_VER is defined
_WIN32 is defined
2. 在MinGW下编译 输出下面的信息
sizeof(int)=32
sizeof(int*)=32
__GNUC__ is defined
__i386__ is defined
_WIN32 is defined
3. 在64位Fedora19, 使用gcc -m32 编译,输出下面的信息
sizeof(int)=32
sizeof(int*)=32
__GNUC__ is defined
__i386__ is defined
__linux__ is defined
4. 在VC2010, 64位模式下编译,输出下面的信息
sizeof(int)=32
sizeof(int*)=64
_MSC_VER is defined
_WIN32 is defined
_WIN64 is defined
5. 在MinGW64下编译 输出下面的信息
sizeof(int)=32
sizeof(int*)=64
__GNUC__ is defined
__x86_64__ is defined
_WIN32 is defined
_WIN64 is defined
__amd64 is defined
6. 在64位Fedora19, 使用gcc -m64 编译,输出下面的信息
sizeof(int)=32
sizeof(int*)=64
__GNUC__ is defined
__x86_64__ is defined
__linux__ is defined
__LP64__ is defined
__amd64 is defined
注:在VC下直接用集成环境编译,在MinGW和Linux下直接使用 gcc来编译。