reinterpret_cast between ponter and different size intgeral type

c++, casting, implicit-conversion

Solution

All conversions between pointers and integral types are implementation defined. The only guarantee the standard makes is that:

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

The standard does, however, make the statement (in a non-normative note) that:

It is intended to be unsurprising to those who know the addressing structure of the underlying machine.

From a quality of implementation point of view, if the machine has linear addressing, casting an `int` to a pointer should result in a value that corresponds to the value of the `int`, if the word (whatever its size) is viewed as an integral type; in other words, the bit pattern isn't changed. If the integral type is smaller, and is negative, it is an open question whether it should be sign extended, or whether the remaining bits should be set to 0. I prefer the second, but I think that both can be considered "unsurprising".

From a pragmatic point of view: there's a significant amount of software out there which will occasionally cast a small non-negative integral value to `void*`, and expects to get it back with a cast later. Formally, getting it back requires converting first to a `intptr_t` (or larger); otherwise the code shouldn't compile. But I can't imagine a compiler breaking this otherwise. For negative values, on the other hand, I'd feel significantly less sure. And I'm not sure how small is small, either. (I currently use the technique in one special case for values less than some 40 or 50. I works with MSC, g++ and Sun CC, at least, and I can't imagine it failing on any of the other mainstream Unix machines I've used in the past. But I wouldn't count on it on a 16 bit Intel, or some of the other more exotic machines I've seen, and certainly not on an embedded system.)

Finally, as for your exact questions: it could vary. I'd try it and see, counting on the fact that whatever it does, there's some code somewhere which counts on it doing that, and that the vendor won't risk changing the behavior. Formally, since it is implementation defined, the implementor is required to document it (and could, of course, change it in the next version), but I've generally found it very, very difficult to find this documentation.

EDIT:

I just noticed that your final question concerned `unsigned long long` to `int`. This is an integral conversion, and not a `reinterpret_cast`, so different rules apply. Or rather, the rules are specified in a different section: the basic rule is still "implementation defined":

If the destination type is signed, the value is unchanged if it can be represented in the destination type (and bit-field width); otherwise, the value is implementation-defined.

The C standard is somewhat different here, in that it explicitly allows an implementation defined signal to be raised. (It's stretching it somewhat to say that the "value" in the C++ standard could be the raising of a signal, even if this would be the preferred implementation.) In practice: all of the compilers I know just ignore the extra high order bits.

Problem

What actually happens when we do the following: 1) ``` int i = -1; // 32 bit void *p; p = reinterpret_cast<void*>(i) ``` on 64 bit architecture, sizeof(void*) == 8 2) ``` long long i; // 64 bit void *p = (unsigned int)(-1); i = retinterpret_cast<long long>(p) ``` on 32 bit architecture sizeof(void*) = 4 I generally understand what will be the result, but I want somebody to describe the mechanism in terms of the C++ standard for better understanding. In the second case the behaviour is like those described in "integral promotions"(4.5) (i will be -1) for the case "int - unsigned long", so do we generally say that pointers are converted like signed integers? 3) ``` int i = ...; unsigned long long L = ...; i = L; ``` What rules apply here?

Original source