How to resolve: “cast to pointer from integer of different size” warning in C code?

走远了吗. 提交于 2019-12-21 09:10:13

问题


I am removing gcc warnings from a legacy code.

Is it possible to suppress the warning "cast to pointer from integer of different size" through typecasting:

example:

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

Can someone please guide me how to resolve such gcc warnings?


回答1:


First, if you can fix func (are allowed to modify its source), then fix it. If its computations can be done with pointers, then do them with pointers and return pointers. Sometimes there are valid reasons to work with addresses as integers (e.g., dealing with alignment issues in special code). In that case, change func to use the uintptr_t type (defined in stdint.h). It is designed for treating pointers as integers when necessary. (There is also intptr_t if signed arithmetic is better for some reason, but I generally find the unsigned uintptr_t to be less troublesome.) Preferably, func should convert the uintptr_t to a pointer when returning it, so the return type of func would be a pointer (to something, perhaps some_struct or void).

If you cannot fix func, then you can use casts to tell the compiler that you intend to do the conversions that are being performed. However, this particular error message is telling you that you are not merely converting an integer to a pointer, but that you are converting an integer of one size (e.g., four bytes) to a pointer of another size (e.g., eight bytes). It is likely this code was originally written for a system where the integer type returned by func had the same size as the pointer type, but you are now compiling on a system where the pointer type is larger or less than that integer size.

In that case, you must ensure that the computation performed by func works in the new architecture. If it is returning only a 32-bit value, will that always hold the correct value? That is, nothing will be lost by the missing high 32 bits? No address that func should calculate ever exceeds the maximum value of the integer type it uses? If func is using signed integer types, consider the sign bit too.

If you have ensured that the value returned by func is correct, then you can use explicit casts, such as: some_struct *ptr = (some_struct *) (intptr_t) func();.




回答2:


My gcc does not give the warning you cited. It would also be strange because there is no cast in your code.

I get the warning

assignment makes pointer from integer without a cast

Note the "without a cast" part. Thus you can make gcc silent by casting (without changing the behaviour):

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

Then, you will get your warning ("cast to pointer from integer of different size") iff the return type of func does not fit for addresses. This can be silenced by additionally casting func() to a suitable integer type, e.g. intptr_t:

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

All this under the assumption you really want to convert the wrong-sized integer to a pointer. Probably, reworking the code is a better idea.




回答3:


There are two possibilities here:

  1. func is casting an actual pointer to an integer; it is later used as a pointer.
  2. func is returning an integer that is being stored in a pointer; ptr is later cast to an integer and used as an integer.

In the first case, the return value from func will lose information, and potentially crash or worse, if int is smaller than the size of a data pointer, which it will be on most 64-bit memory models (including Windows and Linux). In that case you should change the return type of func to intptr_t; see Using intptr_t instead of void*? and Why / when to use `intptr_t` for type-casting in C?.

In the second case, it's less of an issue but to deal with endianness issues you should cast through intptr_t: some_struct *ptr = (some_struct *)(intptr_t)func(); and later int value = (int)(intptr_t)ptr;. See GLib Type Conversion Macros for a discussion of the issue.



来源:https://stackoverflow.com/questions/11796909/how-to-resolve-cast-to-pointer-from-integer-of-different-size-warning-in-c-co

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!