The C standard is fairly detailed in listing possible problems, C17 6.3.2.3/5:
An integer may be converted to any pointer type. Except as previously specified, the result is implementation-defined, might not be correctly aligned, might not point to an entity of the referenced type, and might be a trap representation.
So the various potential problems are:
Different sizes. This is the most obvious issue. A pointer address might not fit inside an integer, or the other way around.
Alignment. An integer containing some random number might cause a misaligned address when converted to a pointer.
Incorrect addresses, such as misaligned ones or addresses pointing into executable code rather than data, may cause implementation defined "traps"/hardware exceptions.
Far less likely, integers can in theory contain trap representations too, but that's likely only relevant for exotic/fictional one's complement and signed magnitude systems. The C standard allows for such systems, but very few such systems have actually existed in the history of computers.
Wrong type. If we lie to the compiler when converting to/from pointers and tell it that there's another type stored at a location than what's actually stored there, we might get into all manner of problems. We may screw up the compiler's internal track of what types that are stored where, so called "strict pointer aliasing violations". This in turn might cause optimization-related bugs.
What is the strict aliasing rule?
We may also, once again, cause problems with misalignment and traps, or just by the program not making any sense of what's stored at a certain location.
Pointer arithemtic on unknown addresses. There may be issues with casting to a physical address where the compiler doesn't know what's stored (no known type) and then perform pointer arithmetic from there. Because pointer arithmetic is only well-defined when pointing at an array of a known type. Strictly speaking, doing so is undefined behavior, so it might cause some poor compiler implementations to bug out and produce random behaving code. Hosted system compilers are known to do this - it's a quality of implementation problem. In particular, be very afraid of such bugs when using the gcc compiler for embedded systems programming.
Exotic pointer formats. Some systems utilize extended addressing modes, that go beyond the default address bus width. This is very common in low-end embedded systems with 8-/16 bit addresses, but also existed in the PC world back in the MS DOS days. Typically such extended addresses are using a non-standard pointer type (a common non-standard extension is the far
keyword). Converting to/from these pointers types and integers will be very system-specific.
The most correct type to use for converting to/from pointer types is uintptr_t
. This is defined to be "large enough" and suitable to hold the representation of a pointer.
On some exotic systems we may also use intptr_t
which is the signed equivalent. That one only makes sense if the OS has some weird internal virtual addressing, such as placing kernel space at negative addresses.