Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Byte array to int in C++

Tags:

c++

Would the following be the most efficient way to get an int16 (short) value from a byte array?

inline __int16* ReadINT16(unsigned char* ByteArray,__int32 Offset){
    return (__int16*)&ByteArray[Offset];
};

If the byte array contains a dump of the bytes in the same endian format as the machine, this code is being called on. Alternatives are welcome.

like image 644
user826228 Avatar asked Jul 28 '11 06:07

user826228


2 Answers

It depends on what you mean by "efficient", but note that in some architectures this method will fail if Offset is odd, since the resulting 16 bit int will be misaligned and you will get an exception when you subsequently try to access it. You should only use this method if you can guarantee that Offset is even, e.g.

inline int16_t ReadINT16(uint8_t *ByteArray, int32_t Offset){
    assert((Offset & 1) == 0); // Offset must be multiple of 2
    return *(int16_t*)&ByteArray[Offset];
};

Note also that I've changed this slightly so that it returns a 16 bit value directly, since returning a pointer and then subsequently de-referencing it will most likely less "efficient" than just returning a 16 bit value directly. I've also switched to standard Posix types for integers - I recommend you do the same.

like image 163
Paul R Avatar answered Oct 08 '22 23:10

Paul R


I'm surprised no one has suggested this yet for a solution that is both alignment safe and correct across all architectures. (well, any architecture where there are 8 bits to a byte).

inline int16_t ReadINT16(uint8_t *ByteArray, int32_t Offset)
{
    int16_t result;
    memcpy(&result, ByteArray+Offset, sizeof(int16_t));
    return result;
};

And I suppose the overhead of memcpy could be avoided:

inline int16_t ReadINT16(uint8_t *ByteArray, int32_t Offset)
{
    int16_t result;
    uint8_t* ptr1=(uint8_t*)&result;
    uint8_t* ptr2 = ptr1+1;
    *ptr1 = *ByteArray;
    *ptr2 = *(ByteArray+1);
    return result;
};

I believe alignment issues don't generate exceptions on x86. And if I recall, Windows (when it ran on Dec Alpha and others) would trap the alignment exception and fix it up (at a modest perf hit). And I do remember learning the hard way that Sparc on SunOS just flat out crashes when you have an alignment issue.

like image 29
selbie Avatar answered Oct 08 '22 23:10

selbie