x64 兼容 C 源代码

发布于 2024-08-14 16:14:08 字数 904 浏览 2 评论 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*)

I think I know what #ifdefs I need to use to be x86-32 and x86-64 compatible on both msvc and gcc, see below. Is this complete for those platforms?

#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

Are IA64 and x86 64 the same from a C programmer's perspective?

I'd also like to be able to compile on Macs. What do I add?

Edit: I can't use sizeof(), as I'm dealing with untouchable legacy code that use stuff like #if SIZEOF_VOIDP == SIZEOF_LONG. I am also only interested in the architectures, not the actual contents. Note that the precompiler does not allow #if sizeof(size_t) == sizeof(void*).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

握住你手 2024-08-21 16:14:08

如何使用您的构建系统将它们生成为常量

#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 中处理问题在 64 位 ia64 和 x64 Windows 上,您的 sizeof(long) 错误(即使使用您假设为非 Windows 的 gcc 编译器)。

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

How about using your build system to generate these as constants

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

Provided your build system is consistent, where everything is built with the same options, this builds in implicit portability, and you deal with the problems in your ifdefs where you've got sizeof(long) wrong on 64-bit ia64 and x64 windows (even with the gcc compiler which you've assumed to mean non-windows).

Backing this up with the static asserts mentioned in a different answer would then give you the best of both worlds.

超可爱的懒熊 2024-08-21 16:14:08

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

In C++ with 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 上安装的 long 和 void* 都占用 4 个字节。

If you're doing a lot of cross-platform/cross-compiler work then it may be worth adding static asserts for those constants so you can at least catch platform/compiler combinations that are not set in your ifdefs.

In C++ with boost:

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

If you're working in C there are a couple of questions on here about implementing static assertions in C.

Macs use a customised version of GCC, so many of the constants you use for GCC should also work on the Mac. I typically detect OSX builds with

#ifdef __APPLE__
#endif

but I'm not sure if this is the best way. On my (32-bit) 10.4 OSX install both a long and void* occupy 4 bytes.

離殇 2024-08-21 16:14:08

所有这些定义对我来说看起来都很多余。只需使用 sizeof(void*) 和朋友即可。

如果您需要定义常量,请像这样定义它们

#define SIZEOF_VOIDP sizeof(void*)

All those defines look pretty reduntant to me. Just use sizeof(void*) and friends.

If you need to have your constants defined, define them like

#define SIZEOF_VOIDP sizeof(void*)
不忘初心 2024-08-21 16:14:08

为什么不使用 sizeof 运算符?

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

Why don't you use sizeof operator?

sizeof(long);
sizeof(int);
sizeof(void*);
七禾 2024-08-21 16:14:08

提防!在 Windows 上,无论您是 i386(即 x86_32)还是 x86_64,您都会有 sizeof(long) == 4代码>! (或#define SIZEOF_LONG 4)。而 sizeof(void *) == 8

sizeof(long) != sizeof(void *)

Beware! On Windows, whether you are i386 (i.e. x86_32) or x86_64, you will have sizeof(long) == 4 ! (Or #define SIZEOF_LONG 4). Whereas sizeof(void *) == 8 !

sizeof(long) != sizeof(void *)

忆伤 2024-08-21 16:14:08

关于 #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

One point to consider about #define SIZEOF_LONG 8 and #define SIZEOF_VOIDP 8.

On HP-UX IA64 this program:

#include <iostream>

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

if compiled like this:

g++ -mlp64 main.cpp

gives:
8
8

but if compiled like this:

g++ -milp32 main.cpp

gives
4
4

零時差 2024-08-21 16:14:08

不,它还不完整。

只有 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

...

No, it is not complete.

Only sizeof (char) is the same on all platforms, compiler options, ...
All other types are not guaranteed to be the same, to stay the same after compiling with different options, ...

You need

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

...
青芜 2024-08-21 16:14:08

//这可能有助于理解

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

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

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

一点 GNU 编译器无法解析此 #if(sizeof(int) == 4)
他退出并显示错误消息!

//may be this helps to understand

//with MSC or BORLAND it was possible to do this

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

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

the GNU Compiler don't resolve this #if(sizeof(int) == 4)
he quit this with error message!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文