3

我试图移植到 64 位的 C 源代码在 32 位环境中运行时没有任何警告。当我使用 compile gcc (Ubuntu 4.4.1-4ubuntu9) 4.4.1 在 64 位 Linux 环境中编译时,它主要显示以下警告:

warning: cast to pointer from integer of different size

上面的警告是最多的。我使用了uintptr_t类型,大部分警告都被删除了。我可以使用uintptr_t将类型int /unsigned int更改为 有利的 64 位。但是如何更改以下类型以兼容 64 位:

typedef void*  POINTER;

我更改了以下代码:

typedef unsigned int    ABC; 

进入

typedef uintptr_t ABC

我收到以下警告:

warning: passing argument 2 of ‘function’ from   incompatible pointer type
note: expected ‘ABC *’ but argument is of type ‘unsigned int *’

此外,在将类型 def 更改为早期的 int 或 unsigned int 的 uintptr_t 后,我​​遇到了以下大部分警告:

warning: inlining failed in call to ‘abc_StringCopy’: call is unlikely and code size would grow

函数 tptp_StringCopy 如下:

static __inline__ char* abc_StringCopy(void)
{
  char *copy;
  copy = (char*)Malloc(yyleng+1);
  strcpy(copy, yytext);
  return copy;

我怎样才能摆脱这些警告?

4

4 回答 4

2

unsigned intuintptr_t不能与64 位系统互换。int并且unsigned int在 64 位机器上仍然是 32 位值,但uintptr_t变成了 64 位类型。之所以调用该类型,uintptr_t是因为该类型是一个与指针宽度相同的无符号整数值。这意味着uintptr_t在 32 位机器上是 32 位宽,但在 64 位机器上变成 64 位宽。

在您的代码中,这意味着随着您的typedef更改,在 64 位机器NAT*上是一个指向 64 位变量unsigned int*的 64 位指针,但是是一个指向 32 位变量的 64 位指针。

clause_ComputeSplitFieldAddress仍在期待unsigned int*参数。

于 2010-03-06T21:41:34.870 回答
1

我怀疑这里的基本问题是假设可以将指针转换为 32 位整数类型和从 32 位整数类型转换而不会造成任何损失。对于 32 位代码,这是正确的,对于 64 位代码,则不是 - 指针是 64 位类型。这可能是最常见的 32 位到 64 位移植问题。

NAT 的实际用途是什么?如果它是指向结构的不透明指针(在 32 位代码中装扮成 32 位整数),则最好将其声明为 void* 而不是 uintptr_t。

于 2010-03-06T22:54:16.253 回答
1

没有明显的理由改变 POINTER typedef;void 指针在 32 位和 64 位中仍然是 void 指针(尽管 32 位版本占用 64 位版本的一半空间)。只有当您滥用 POINTER 并尝试将其视为某种整数时,您才会遇到问题。

您没有显示clause_ComputeSplitFieldAddress 的代码,但很明显,当函数采用“NAT *”时,您不能传递“unsigned int”的地址;您将不得不查看调用它的位置并决定修复调用代码的适当操作 - 基本上,将相关的 unsigned int 变量更改为 NAT 变量。

对于 tptp_StringCopy 函数,也许您应该使用strdup()- ,然后如果内存分配失败,您可能不会立即崩溃。

您没有显示与 List_Cons() 相关的警告,因此我们无法提供帮助。

通常,您可以通过确保不在整数和指针之间进行类型双关来处理许多 32 位到 64 位问题。如果必须,请使用 uintptr_t (因此使用<inttypes.h>)。<inttypes.h>当您有特定 typedef 名称的变量类型定义时,请使用严格定义的打印和扫描格式。例如,使用

PRIXPTR

格式化 uintptr_t 值:

printf("0x%08" PRIXPTR "\n", ptr_as_int);

这不会解决所有问题。它会处理很多。

如果想要对未内联的代码进行警告,编译器有权向您发出警告。除了不要求内联不能内联的函数外,您对此无能为力。

于 2010-03-07T02:36:12.720 回答
-1

我不是很清楚情况,但似乎您已更改unsigned intuintptr_t. 前者是无符号整数,后者是无符号整数指针

一般来说,这不是一个有效的替代品。

此外,您说代码“在 32 位上运行时没有警告”,但 64 位编译会给您警告。但它是否在没有警告的情况下运行并不重要。也许你的意思是,它编译时没有警告。真的吗?您修改的代码编译为 32 位而没有警告?那将是一个惊喜。

于 2010-03-06T20:58:44.430 回答