2010-02-12 35 views
3

在编写应该可在32位和64位计算机上移植的代码时应该记住哪些要点?要考虑编写可移植到32位和64位体系结构的代码的要点

思考更多关于这一点,我觉得如果你能interms面临问题,这将有助于增加你的经验。

这个雪上加霜的是,有一次我遇到一个问题,由于缺少原型为其返回返回一个指针的函数。当我将它移植到一台64位机器上时,代码崩溃了,我不知道相当一段时间的原因,后来才意识到所有丢失的原型都被假定返回int来引起问题。

任何这样的例子都可以提供帮助。

编辑:添加到社区wiki。

+3

社区wiki? – jamessan 2010-02-12 18:40:20

+0

请参阅http://stackoverflow.com/questions/411798/converting-32-bit-application-into-64-bit-application-in-c – Christoph 2010-02-12 18:42:29

+0

和http://stackoverflow.com/questions/534941/team-is -XP32-to-xp64-for-net-development-any-gotchas/535154#535154 – lsalamon 2010-02-12 18:46:41

回答

2

陷阱:

  1. 转换指针为整数类型是危险
  2. 数据结构的大小可以改变
  3. 当心符号扩展
  4. 不同ABI?

一些技巧&技巧我发现有帮助:

  1. 让自己的本机大小的整数类型(从头部或typedef你自己的),并使用它时,你有没有变数关心大小。
  2. 使用明确的变量类型尽可能(u_int64_t,int_32_t等)
3
  • 一些积分类型可以具有不同的尺寸
  • 指针是不同长度的
  • 结构填充
  • 对齐

在Windows上,仅呼吁在x64约定,而不是将M在普通的x32机器上重复使用。

当你有一些32位和64位的组件时,事情会变得更加混乱。在Windows上,我最终写了一个COM服务让他们说话。

3

将指针推入堆栈占用两倍的空间。尽管堆栈大小在操作系统版本之间可能不会改变,导致在32位编译运行良好的代码在64位编译和运行时发生神秘故障。不要问我怎么知道这一点。

+0

我从来没有听说过这个。这真的会影响吗? – Jay 2010-02-12 18:51:05

+0

呃...是啊... – 2010-02-12 19:05:41

+0

只有当编译器不能/不将指针存储在寄存器中时,才是如此。 – philant 2010-04-30 15:11:41

2

编写自动化测试并在两个平台上定期运行测试。

3

sizeof(int)might!= sizeof(void *)

alignment。对齐需求可能会发生变化。这可以暴露错误的地方,如果接受者期待指针,则不应该将0传递给可变参数。如果接收者期待指针,则可以将0忽略到应该已经对齐的对象中,但仅在32位(或者在不关心的处理器上)这在C++中很痛苦,在这种情况下,精明的开发人员知道0是一个有效的空指针。 C开发人员通常会使用NULL,因此您可能确定

+0

+1现在我想知道如果这种行为是合规的。该标准说空值计算为0.它不应该被默认提升为(void *)吗?不是你不应该使用NULL,而是阅读标准,头文件编写者可以将NULL定义为0. http://www.open-std.org/JTC1/SC22/wg14/www/docs/n1425.pdf请参阅point 3对6.3.2.3。这听起来像GCC是错误的,或者一旦这是目前的标准将是错误的。 – jbcreix 2010-02-12 23:07:14

+0

在我的情况下,gcc将NULL转换为nullptr。所以它工作。我同意,如果NULL被定义为0,那么它不会修复我的错误,在这种情况下,我将不得不明确地说(void *)0 – pm100 2010-02-13 00:43:05