我试图在32位环境中没有任何警告的情况下尝试移植到64位的C源代码。当我使用编译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更改为uintptr_t(早于int或unsigned int)之后,我遇到大多数警告,如下所示:
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;
如何摆脱这些警告?
答案 0 :(得分:2)
unsigned int
与uintptr_t
不可互换。 int
和unsigned int
在64位计算机上仍为32位值,但uintptr_t
成为64位类型。类型被称为uintptr_t
的原因是因为类型是无符号整数值,其宽度与指针相同。这意味着uintptr_t
在32位机器上为32位宽,但在64位机器上为64位宽。
在您的代码中,这意味着,在typedef
更改时,在64位计算机上NAT*
是指向64位变量的64位指针,但unsigned int*
是一个指向32位变量的64位指针。
clause_ComputeSplitFieldAddress
仍然期待unsigned int*
个参数。
答案 1 :(得分:1)
我怀疑这里的根本问题是某些东西假设一个指针可以转换为32位整数类型而不会丢失。使用32位代码确实如此,64位代码不是 - 指针是64位类型。这可能是最常见的32位到64位移植问题。
NAT实际上是什么意思?如果它是一个指向结构的不透明指针(在32位代码中打扮成32位整数),则最好将其声明为void *而不是uintptr_t。
答案 2 :(得分:1)
没有明显的理由改变POINTER typedef; void指针仍然是32位和64位的空指针(尽管32位版本占用64位版本的一半空间)。只有当你滥用POINTER并尝试将其视为某种整数时才会遇到问题。
您没有显示clause_ComputeSplitFieldAddress的代码,但显然当函数采用'NAT *'时,您无法传递'unsigned int'的地址;您将不得不查看它的调用位置并决定修复调用代码的相应操作 - 基本上,将相关的unsigned int变量更改为NAT变量。
对于tptp_StringCopy函数,也许您应该使用strdup()
- 如果内存分配失败,您可能不会立即崩溃。
您没有显示与List_Cons()相关的警告,因此我们无法随时提供帮助。
通常,您可以通过确保不在整数和指针之间进行类型惩罚来处理许多32位到64位的问题。如果必须,请使用uintptr_t(因此<inttypes.h>
)。当您具有特定typedef名称的变量类型定义时,严格使用<inttypes.h>
中定义的打印和扫描格式。例如,使用
PRIXPTR
格式化uintptr_t值:
printf("0x%08" PRIXPTR "\n", ptr_as_int);
这不会解决所有问题;它将处理很多它们。
如果想要了解未内联的代码,编译器有权发出警告。除了没有请求内联无法内联的函数之外,你无能为力。
答案 3 :(得分:-1)
我对情况并不十分清楚,但您似乎已将unsigned int
更改为uintptr_t
。前者是unsigned int,后者是unsigned int 指针。
一般来说,这不是一个有效的替代品。
另外,你说代码“在32位没有警告的情况下运行”但是64位的编译会给你警告。但它是否在没有警告的情况下运行并不重要。也许你的意思是,它编译没有警告。真的吗?您修改过的代码在没有警告的情况下编译为32位?那将是一个惊喜。