How to Cast Integer Value to Pointer Address Without Triggering Warnings

女生的网名这么多〃 提交于 2020-04-13 03:47:11

问题


I have the following variable

uint32_t Value = 0x80

0x80 represents an address in the memory e.g.

// Write 2 at address 0x80
*(uint32_t*)((uint32_t)0x80) = 2;

How can i cast Value to a Pointer, so it points to 0x80?

uint32_t *Pointer = ?? Value;

This:

(uint32_t*)(uint32_t)Value;

returns:

warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]

回答1:


To handle integer to object pointer conversion, use the optional integer uintptr_t or intptr_t types. Function pointers are a separate matter.

The following type designates an unsigned integer type with the property that any valid pointer to void can be converted to this type, then converted back to pointer to void, and the result will compare equal to the original pointer C11dr 7.20.1.4 1

uintptr_t

Then convert the void * to the desired type.

#include <stdint.h>
uintptr_t Value = 0x80;
uint32_t *Pointer = (void *) Value;

If 0x80 was not derived from a valid uint32_t *, the result in undefined behavior (UB). Yet it sounds like OP is on a platform with memory mapped data locations.




回答2:


I will spell it out for you: given

uint32_t Value = 0x80;

you want

*((uint32_t *)(uintptr_t)Value) = 2;

The type uintptr_t, if it exists, is guaranteed to be castable to and from arbitrary pointer types without loss of information. It is not guaranteed to exist, but on platforms where it doesn't exist, what you're trying to do cannot safely be done without a great deal more information.

No other type is officially guaranteed to have this property; however, "cpp plus 1" is correct that size_t usually also does. I would go so far as to say that any ABI for a flat-memory architecture, that doesn't make size_t have this property, was specified incorrectly, but they do exist and sometimes you have to work with them.

It would be better to declare Value with a pointer type in the first place:

uint32_t *const Value = (uint32_t *)(uintptr_t)0x80;

because then you only have to write the casts when you initialize it, not when you use it,

*Value = 2;

and you probably have a bunch of places where you use it. This also avoids a potential problem if it happens that sizeof(uintptr_t) < sizeof(uint32_t), as uint32_t is never involved in the address arithmetic; the compiler may complain if the cast from 0x80 to uintptr_t actually truncates the constant, but that shouldn't ever happen with the real memory addresses you are accessing this way.



来源:https://stackoverflow.com/questions/45220134/how-to-cast-integer-value-to-pointer-address-without-triggering-warnings

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