I read the question as "is this reinterpret_cast" legal and well-defined in
std C++. In that case the answer is a clear YES. If the question is in the
above code can determine all types of endianness, those in existence now as
well as any conceivable ones, then of course the answer is NO.
Legal, yes. Well-defined, no. Probably work, yes. The requirement
(at least, in older standards) is that reinterpret_cast will convert
between object pointers, though the result is unspecified (not
undefined, but not well-defined). Here is the section of the 1996
draft standard stating the requirement:
5.2.10/7:
<quote>
A pointer to an object can be explicitly converted to a pointer to
an object of different type*. Except that converting an rvalue of type
"pointer to T1" to the type "pointer to T2" (where T1 and T2 are
object types and where the alignment requirements of T2 are no
stricter than those of T1) and back to its original type yields the
original pointer value, the result of such a pointer conversion is
unspecified.
* The types may have different cv-qualifiers, subject to the overall
restriction that a reinterpret_cast cannot cast away constness.
</quote>
Note that "object" in the quote above includes built-in types. Note
also that while one could imagine an architecture where the alignment
for chars is stricter than for ints, a real-world computer with such
an alignment scheme would be quite perverse (especially considering
that sizeof(int) >= sizeof(char)).
As long as all memory locations which can store an int can be
addressed by a char*, it's possible the original test to work under a
decent (whatever that means) compiler.
For the original test to work, it's not sufficient that pointer
conversion be value-preserving (i.e. the number of possible values for
pointers to two different types are the same, i.e. all pointers are of
the same size). This will guarantee pointer conversions will be
invertible, but there still may be some integer pointers which cannot
be converted to a char* which points to the same location as the int*.
For example, consider an architecture where int pointers are aligned
by shifting insignificant bits (e.g. an int32_t* with value 0x10
points at memory location 0x40) and all pointers are of the same size.
int pointers address the same number of locations as char pointers but
can address memory outside of the char arena (the maximum memory size
for the integer arena is sizeof(int) times greater than the char
arena). The original test will fail if 'i' happens to be located at a
memory location where a char* cannot point. There's a kind of
symmetry here: a char* can point inside the int arena where an int*
cannot point and an int* can point outside of the char arena where a
char* cannot point. (As a side note, pointer conversion by shifting
on such a machine is not compliant, as shifting is not invertible in
all cases; conversion by rotation, however, is compliant.)
As another approach to the original question, consider the following
gleaned from Stroustrup: any object pointer can be implicitly
converted to a void*, and a void* can be explicitly converted to a
pointer to any object type. This implies that (via conversion to a
void*) an int* can be converted to a char*, though it doesn't
guarantee that the resultant char* points to the same memory location
as the original int*.
Delving into this really made me glad I'm not responsible for the
standard.
Kanenas