x64兼容C源

时间:2009-12-17 12:02:34

标签: c 64-bit portability itanium

我想我知道在msvc和gcc上我需要使用的#ifdefs是x86-32和x86-64兼容,见下文。这些平台是否完整?

#if defined(_MSC_VER)
#  if defined(_M_IA64) || defined(_M_X64)
#    define SIZEOF_SIZE_T 8
#    define SIZEOF_VOIDP  8
#  elif defined(_M_IX86)
#    define SIZEOF_SIZE_T 4
#    define SIZEOF_VOIDP  4
#  else
#    error "Unsupported MSVC platform"
#  endif
#elif defined(__GNUG__)
#  if defined(__x86_64__) || defined(__ia64__)
#    define SIZEOF_SIZE_T 8
#    define SIZEOF_VOIDP  8
#  elif defined(__i386__)
#    define SIZEOF_SIZE_T 4
#    define SIZEOF_VOIDP  4
#  else
#    error "Unsupported GCC platform"
#  endif
#endif

从C程序员的角度来看,IA64和x86 64是否相同?

我也希望能够在Mac上编译。我要添加什么?

编辑:我无法使用sizeof(),因为我正在处理使用#if SIZEOF_VOIDP == SIZEOF_LONG等内容的不可触及的遗留代码。我也只对架构感兴趣,而不是实际内容。请注意,预编译器不允许#if sizeof(size_t) == sizeof(void*)

8 个答案:

答案 0 :(得分:6)

如何使用构建系统将这些作为常量生成

#include <stdio.h>

int main()
{
   printf(
      "#if !defined ARCH_MODEL_CONSTANTS_H\n"
      "#define ARCH_MODEL_CONSTANTS_H\n"
      "\n"
      "#    define SIZEOF_LONG  %u\n"
      "#    define SIZEOF_VOIDP %u\n"
      "\n"
      "#endif\n",
      (unsigned)sizeof(long),
      (unsigned)sizeof(void *) ) ;

   return 0 ;
}

如果您的构建系统是一致的,所有内容都使用相同的选项构建,那么这将构建隐式可移植性,并且您处理ifdef中出现sizeof(long)错误的问题在64位ia64和x64窗口上(即使使用gcc编译器,你认为这意味着非窗口)。

使用不同答案中提到的静态断言对此进行备份将为您提供两全其美的优势。

答案 1 :(得分:2)

所有这些定义对我来说都是多余的。只需使用sizeof(void*)和朋友。

如果您需要定义常量,请将它们定义为

#define SIZEOF_VOIDP sizeof(void*)

答案 2 :(得分:2)

如果您正在进行大量的跨平台/交叉编译工作,那么为这些常量添加静态断言可能是值得的,因此您至少可以捕获未在ifdef中设置的平台/编译器组合。

在C ++中使用boost:

#include <boost/static_assert.hpp>
BOOST_STATIC_ASSERT(sizeof(void*) == SIZEOF_VOIDP)
BOOST_STATIC_ASSERT(sizeof(long)  == SIZEOF_LONG)

如果您在C中工作,那么有关于在C中实现静态断言的几个问题。

Mac使用GCC的自定义版本,因此您用于GCC的许多常量也应该在Mac上运行。我通常使用

检测OSX构建
#ifdef __APPLE__
#endif

但我不确定这是不是最好的方法。在我的(32位)10.4 OSX安装上,长和空*占用4个字节。

答案 3 :(得分:1)

为什么不使用sizeof运算符?

sizeof(long);
sizeof(int);
sizeof(void*);

答案 4 :(得分:1)

小心!在Windows上,无论您是i386(即x86_32)还是x86_64,您都会sizeof(long) == 4! (或#define SIZEOF_LONG 4)。而sizeof(void *) == 8

sizeof(long) != sizeof(void *)

答案 5 :(得分:1)

要考虑#define SIZEOF_LONG 8#define SIZEOF_VOIDP 8

在HP-UX IA64上,此程序:

#include <iostream>

int main()
{
#if defined(__ia64__) && defined(__GNUG__)
    std::cout << sizeof(long) << std::endl;
    std::cout << sizeof(void*) << std::endl;
#endif
    return 0;
}

如果这样编译:

g++ -mlp64 main.cpp

给出: 8 8

但如果像这样编译:

g++ -milp32 main.cpp

给出 4 4

答案 6 :(得分:0)

不,它不完整。

在所有平台上只有sizeof (char)相同,编译器选项,...
所有其他类型不保证是相同的,在使用不同的选项编译后保持不变,...

你需要

sizeof (short)
sizeof (int)
sizeof (long)
sizeof (long long) // C99
sizeof (float)
sizeof (double)
sizeof (long double) // C99
sizeof (void *)
sizeof (char *)
sizeof (long double *) // C99

...

答案 7 :(得分:0)

//这可能有助于理解

//使用MSC或BORLAND可以做到这一点

#if(sizeof(int) == 4)
    typedef int32  int;
#endif

#if(sizeof(int) == 8)
    typedef int64  int;
#endif

GNU编译器无法解决此问题#if(sizeof(int) == 4) 他退出了这个错误信息!