如何解决:在C代码中“从不同大小的整数转换为指针”警告?

时间:2012-08-03 13:39:37

标签: c pointers gcc-warning

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

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

example:

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

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

3 个答案:

答案 0 :(得分:20)

首先,如果您可以修复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();

答案 1 :(得分:7)

我的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();

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

答案 2 :(得分:3)

这里有两种可能性:

  1. func正在转换一个指向整数的实际指针;它后来被用作指针。
  2. func返回一个存储在指针中的整数; ptr稍后被转换为整数并用作整数。
  3. 在第一种情况下,func的返回值将丢失信息,如果int小于数据指针的大小,则可能会崩溃或更糟它将在大多数64-bit memory models(包括Windows和Linux)上。在这种情况下,您应该将func的返回类型更改为intptr_t;请参阅Using intptr_t instead of void*?Why / when to use `intptr_t` for type-casting in C?

    在第二种情况下,这不是一个问题,但是为了处理字符串问题,您应该通过intptr_tsome_struct *ptr = (some_struct *)(intptr_t)func();以及之后的int value = (int)(intptr_t)ptr;进行处理。有关该问题的讨论,请参阅GLib Type Conversion Macros