0

我想我知道我需要使用什么#ifdefs 才能在 msvc 和 gcc 上兼容 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*).

4

8 回答 8

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 ;
}

如果你的构建系统是一致的,所有的东西都是用相同的选项构建的,这就建立了隐式的可移植性,并且你可以处理ifdefsizeof(long)在 64 位 ia64 和 x64 窗口上出错的问题(即使使用 gcc您假设的编译器是指非 Windows)。

使用不同答案中提到的静态断言来支持这一点,将为您提供两全其美的效果。

于 2009-12-17T15:14:39.680 回答
3

如果您正在做很多跨平台/跨编译器的工作,那么可能值得为这些常量添加静态断言,这样您至少可以捕获未在 ifdef 中设置的平台/编译器组合。

在带有升压的 C++ 中:

#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 上安装 long 和 void* 占用 4 个字节。

于 2009-12-17T12:32:56.457 回答
2

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

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

#define SIZEOF_VOIDP sizeof(void*)
于 2009-12-17T12:07:53.750 回答
1

为什么不使用 sizeof 运算符?

sizeof(long);
sizeof(int);
sizeof(void*);
于 2009-12-17T12:07:36.103 回答
1

谨防!在 Windows 上,无论您是i386(ie x86_32) 还是x86_64,您都将拥有sizeof(long) == 4! (或#define SIZEOF_LONG 4)。鉴于sizeof(void *) == 8

sizeof(long) != sizeof(void *)

于 2009-12-17T12:22:20.363 回答
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

于 2009-12-17T12:27:44.233 回答
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

...
于 2009-12-17T12:13:25.053 回答
0

//这可能有助于理解

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

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

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

GNU 编译器没有解决这个问题,#if(sizeof(int) == 4) 他退出了这个错误消息!

于 2013-05-03T07:07:15.560 回答