Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Conversions between integers and pointers can have undesired consequences depending on the implementation. According to the C Standard, Section section 6.3.2.3 [ISO/IEC 9899:2011],

...

This example is noncompliant, for example, on an implementation where pointers are 64 bits and unsigned integers are 32 bits because the result of converting the 64-bit ptr cannot be represented in the 32-bit integer type.:

Code Block
bgColor#ffcccc
langc
void f(void) {
  char *ptr;
  /* ... */
  unsigned int number = (unsigned int)ptr;  /* violation */
  /* ... */
}

...

Any valid pointer to void can be converted to intptr_t or uintptr_t and back with no change in value (see INT11-EX2). The C Standard guaranteeds guarantees that a pointer to void   may be converted to or from a pointer to any object type and and back again and that the result must compare equal to the original pointer.   Consequently, converting directly from a char * pointer to a uintptr_t, as in this compliant solution, is allowed on implementations that support the uintptr_t type.

...

In this code example, the pointer ptr is converted to an integer value. The high-order 9 bits of the number are used to hold a flag value, and the result is converted back into a pointer.   This example is noncompliant, for example, on an implementation where pointers are 64 bits and unsigned integers are 32 bits because the result of converting the 64-bit ptr cannot be represented in the 32-bit integer type.

...

It is sometimes necessary in low-level kernel or graphics code to access memory at a specific location, requiring a literal integer to pointer conversion. In this noncompliant code, a pointer is set directly to an integer constant, where it is unknown whether the result will be as intended.:

Code Block
bgColor#FFcccc
langc
unsigned int *g(void) {
  unsigned int *ptr = 0xdeadbeef;
  /* ... */
  return ptr;
} 

...

Adding an explicit cast may help the compiler convert the integer value into a valid pointer. A common technique is to assign the integer to a volatile-qualified object of type intptr_t or uintptr_t and then assign the integer value to the pointer:

Code Block
bgColor#ccccff
langc
unsigned int *g(void) {
  volatile uintptr_t iptr = 0xdeadbeef;
  unsigned int *ptr = (unsigned int *)iptr;
  /* ... */
  return ptr;
}

...