Home > Mobile >  Is performing indirection from a pointer acquired from converting an integer value definitely UB?
Is performing indirection from a pointer acquired from converting an integer value definitely UB?

Time:12-18

Consider this example

int main(){
  std::intptr_­t value = /* a special integer value */; 
  int* ptr = reinterpret_­cast<int*>(value ); // #1
  int v = *ptr;  // #2
}

[expr.reinterpret.cast] p5 says

A value of integral type or enumeration type can be explicitly converted to a pointer. A pointer converted to an integer of sufficient size (if any such exists on the implementation) and back to the same pointer type will have its original value; mappings between pointers and integers are otherwise implementation-defined.

At least, step #1 is implementation-defined. For step #2, in my opinion, I think it has four possibilities, which are

  1. The implementation does not support such a conversion, and implementation does anything for it.
  2. The pointer value is exactly the address of an object of type int, the result is well-formed.
  3. The pointer value is the address of an object other than the int type, the result is UB.
  4. The pointer value is an invalid pointer value, the indirection is UB.

It means what the behavior of the indirection through the pointer ptr will be depends on the implementation. It is not definitely UB if the implementation takes option 2. So, I wonder whether this case is not definitely UB or is definitely UB? If it is latter, which provisions strongly state the behavior?

CodePudding user response:

The standard has nothing more to say on it than what you quoted. The standard only guarantees the meaning of a integer-to-pointer cast if that integer value was taken from a pointer-to-integer cast. The meaning of all other integer-to-pointer conversions are implementation defined.

And that means everything about them is "implementation defined": what they result in and what using those results will do. After all, the pointer-to-integer-to-pointer round trip spells out that you get the "original value" back. The fact that the resulting pointer has the "original value" means that it will behave exactly like you had copied the original pointer itself. So the standard needs say nothing more on the matter.

The behavior of the pointer taken from an implementation-defined integer-to-pointer cast is... implementation-defined. If an implementation says that supports such conversions, it must spell out what the result of supported conversions are. That is, if there is some "a special integer value" for which a cast to an int* is supported by the implementation, it must say what the result of that cast is. This includes things like whether it pointer to an actual int or whatever.

CodePudding user response:

Is performing indirection from a pointer acquired from converting an integer value definitely UB?

Not always. Here is an example that is definitely not UB:

int i = 42;
std::intptr_t value = reinterpret_cast<std::intptr_t>(&i); 
int* ptr = reinterpret_cast<int*>(value);
int v = *ptr;

This is because converting a pointer to an integer of sufficient size and back to the same pointer type is guaranteed to yield the same pointer value as stated in the rule you quoted. Since the original pointer value was valid for indirection, so is the converted one.

  • Related