When to use reinterpret_cast

Well... My issue comes up from having to load big-endian floats from a file. I can load an unsigned integer easily using this function:
1
2
3
4
5
unsigned int getIntFromChars(unsigned char* arr)
{
    unsigned int x=(arr[0]<<24)|(arr[1]<<16)|(arr[2]<<8)|arr[3];
    return x;
}


Now... Bit shifting and bitwise operations, as far as I'm concerned, are only really useful on unsigned types, because otherwise you run into signed bit shifting and implicit casting issues.

I've read that "reinterpret_cast" should never ever be used. The official specs say "Misuse of the reinterpret_cast operator can easily be unsafe. Unless the desired conversion is inherently low-level, you should use one of the other cast operators." It also says that reinterpret cast is nonportable at best.

Also, from what I understand, this line:
int n=*(reinterpret_cast<int*>(&x))
is equivalent to the c-style cast:
int n=*((int*)(&x))
due to how c-style casting works (implicitly assuming one of the *_cast operators)

So... what Im asking is... is the following bad code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
unsigned int parseBigEndianUInt(unsigned char* arr)
{
    unsigned int x=(arr[0]<<24)|(arr[1]<<16)|(arr[2]<<8)|arr[3];
    return x;
}
int parseBigEndianInt(unsigned char* arr)
{
    unsigned int x=parseBigEndianUInt(arr);
    int n=*(reinterpret_cast<int*>(&x));
    return n;
}
float parseBigEndianFloat(unsigned char* arr)
{
    unsigned int x=parseBigEndianUInt(arr);
    float n=*(reinterpret_cast<float*>(&x));
    return n;
}

and if it is... what's one supposed to do to edit the bitwise values of types?
reinterpret_cast is used when you want to convert one type to another fundamentally different type without changing the bits.

In your first example, you are using reinterpret_cast to cast from unsigned int to int. This is a bad use of reinterpret_cast. Instead, use numeric_cast for this, which will throw if the cast cannot be performed due to a data range error: http://www.boost.org/doc/libs/1_47_0/libs/numeric/conversion/doc/html/boost_numericconversion/improved_numeric_cast__.html

In your second example, you clearly have x which contains a bit pattern that is an integer. Then, you are saying that that bit pattern is actually a float. Somehow, I don't think that's what you want. I think you want static_cast there.
Ack, forgot to say:
The unsigned character array passed in is 4 elements large, and is the byte pattern loaded directly from an ifstream, as is stored in the file (the file is storing everything in a big-endian format). the bit pattern IS actually a float.

As for the integer, the byte array passed in IS the bit pattern of the integer, so the four bytes:

0xFF 0xFF 0xFF 0xFF

would represent the integer -1.

Likewise, a float stored in the file with the four byte/bit pattern

0x00 0x00 0x00 0x01

would not represent the integer 1, or the float 1.0, but instead a very odd floating point value.
I think your use of reinterpret_cast is ok -- if blunt -- in ths case.

The cleverer casts are not appropriate as you are reordering bytes (swapping the order) to where they should be for the other endian-ness.

Not sure what compiler you are using, but intrinsic byte swapping routines are available for Visual C++ (_byteswap_ulong) and gcc (__builtin_bswap32)
Last edited on
Topic archived. No new replies allowed.