Search code examples
c++bit-shiftendiannessinteger-promotion

Conversion of big-endian long in C++?


I need a C++ function that returns the value of four consecutive bytes interpreted as a bigendian long. A pointer to the first byte should be updated to point after the last. I have tried the following code:

inline int32_t bigendianlong(unsigned char * &p)  
{  
  return (((int32_t)*p++ << 8 | *p++) << 8 | *p++) << 8 | *p++;  
}  

For instance, if p points to 00 00 00 A0 I would expect the result to be 160, but it is 0. How come?


Solution

  • The issue is explained clearly by this warning (emitted by the compiler):

    ./endian.cpp:23:25: warning: multiple unsequenced modifications to 'p' [-Wunsequenced]
        return (((int32_t)*p++ << 8 | *p++) << 8 | *p++) << 8 | *p++;
    

    Breaking down the logic in the function in order to explicitly specify sequence points...

    inline int32_t bigendianlong(unsigned char * &p)
    {
        int32_t result = *p++;
        result = (result << 8) + *p++;
        result = (result << 8) + *p++;
        result = (result << 8) + *p++;
        return result;
    }
    

    ... will solve it