11

我正在从遗留代码中删除 gcc 警告。

是否可以通过类型转换抑制警告“从不同大小的整数转换为指针”:

example:

some_struct *ptr = func()  // func() returns an integer.

有人可以指导我如何解决此类 gcc 警告吗?

4

3 回答 3

21

首先,如果你能修复func(允许修改它的源),然后修复它。如果它的计算可以用指针来完成,那么用指针来做它们并返回指针。有时有正当的理由将地址作为整数工作(例如,处理特殊代码中的对齐问题)。在这种情况下,更改func为使用uintptr_t类型(定义在 中stdint.h)。它旨在在必要时将指针视为整数。(也有intptr_t如果有符号的算术由于某种原因更好,但我通常发现无符号uintptr_t的麻烦更少。)最好在返回时将其func转换uintptr_t为指针,因此返回类型func将是指针(指向某物,也许some_structvoid)。

如果您无法修复func,那么您可以使用强制转换告诉编译器您打算执行正在执行的转换。但是,这个特定的错误消息告诉您,您不仅将整数转换为指针,而且将一种大小(例如,四个字节)的整数转换为另一种大小(例如,八个字节)的指针。很可能这段代码最初是为一个系统编写的,其中返回的整数类型func与指针类型具有相同的大小,但您现在正在一个指针类型大于或小于该整数大小的系统上进行编译。

在这种情况下,您必须确保由func新架构执行的计算工作。如果它只返回一个 32 位的值,它会始终保持正确的值吗?也就是说,丢失的高 32 位不会丢失任何东西?没有func应该计算的地址超过它使用的整数类型的最大值?如果func使用有符号整数类型,也要考虑符号位。

如果您确保返回的值func是正确的,那么您可以使用显式转换,例如:some_struct *ptr = (some_struct *) (intptr_t) func();.

于 2012-08-03T13:51:20.707 回答
6

我的 gcc 没有给出你引用的警告。这也会很奇怪,因为您的代码中没有演员表。

我收到警告

assignment makes pointer from integer without a cast

请注意“没有演员表”部分。因此,您可以通过强制转换使 gcc 保持沉默(不改变行为):

some_struct *ptr = (void*)func();

func然后,如果返回类型不适合地址,您将收到警告(“从不同大小的整数转换为指针”) 。这可以通过另外转换func()为合适的整数类型来消除,例如intptr_t

some_struct *ptr = (void*)(intptr_t)func();

所有这一切都假设您真的想将错误大小的整数转换为指针。可能,重新编写代码是一个更好的主意。

于 2012-08-03T13:45:19.070 回答
3

这里有两种可能:

  1. func正在将实际指针转换为整数;它后来被用作指针。
  2. func正在返回一个存储在指针中的整数;ptr稍后转换为整数并用作整数。

在第一种情况下,如果小于数据指针的大小,则 from 的返回值func丢失信息,并且可能会崩溃或更糟,这将在大多数64 位内存模型(包括 Windows 和 Linux)上。在这种情况下,您应该将返回类型更改为; 请参阅使用 intptr_t 而不是 void*?以及为什么/何时在 C 中使用`intptr_t`进行类型转换?.intfuncintptr_t

在第二种情况下,这不是一个问题,而是要处理字节顺序问题,您应该通过intptr_t:some_struct *ptr = (some_struct *)(intptr_t)func();和稍后int value = (int)(intptr_t)ptr;的 . 有关该问题的讨论,请参阅GLib 类型转换宏

于 2012-08-03T13:47:57.477 回答