Gro-Tsen
Gro-Tsen

Reputation: 266

Pointer to integer and back again

First, let me emphasize that this question is legalistic in nature. I am not asking whether the following program will work, in practice, on real implementations, I am asking whether it is legal (:= not producing an undefined behavior) according to the strictest legalistic interpretation of the ISO-9899 standards (:1999 and :2011).

The question is whether it is permissible to convert a pointer to an uintptr_t integer, perform some arithmetic on that integer, return it to the same value, and convert the integer back to a pointer.

So, is the following program legal (in the sense that it does not produce an undefined behavior)?

#include <stdint.h>
#include <stdio.h>
int
main(void)
{
  int answer = 42;  void *ptr;
  uintptr_t deepthought;
  ptr = &answer;
  deepthought = (uintptr_t)ptr;
  ptr = 0;
  deepthought ^= 0xdeadbeef;
  printf("I'm thinking about it...\n");
  deepthought ^= 0xdeadbeef;
  ptr = (void *)deepthought;
  printf("The answer is: %d\n", *((int *)ptr));
  return 0;
}

Again, I am aware that this code will cause no difficulty on any real system. The question is whether it lives up to the legalese in the C standard, esp. §7.18.1.4 in ISO-9899:1999 / §7.20.1.4 in ISO-9899:2011, in which the phrase "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": it isn't clear whether "then converted back" allows for intermediate arithmetic computations.

To make the question a little less theoretical, here is a reason why one might wish for this kind of processing to be forbidden. If we change the example just a little bit so that the pointer is mallocated instead of pointing to a local variable, and if it happens to run on an implementation with a (conservative) garbage-collector, the memory could conceivably be reclaimed during the printf call because, at that moment, there is nothing pointing to that region of memory. So if the C standard makes the above example illegal (e.g., if nothing can be written to a pointer that did not hold a legal pointer value all the time), this provides a legalistic justification for the assumptions made by garbage-collectors.

But I repeat that the question is about the hermeneutics of the C standard, not about any practical or real-world outcome.

Upvotes: 3

Views: 326

Answers (1)

Jens
Jens

Reputation: 72629

Yes, it must work.

From how I read the Standardese, you could write the value of deepthought to a file (say with fwrite), destroy any copies of the value in the program, then read the value from the file again (fread). The value so read and converted to a pointer must compare equal to the original pointer. I don't find any wording that forbids this.

A garbage collector which could move the address of an object would have to take such possibilities into account.

Upvotes: 1

Related Questions