Byte array for int in C ++

Would it be the most efficient way to get the int16 (short) value from an array of bytes?

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

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

+6
source share
5 answers

It depends on what you mean by "efficient", but note that in some architectures this method will fail if Offset is odd, as the resulting 16-bit int will be biased, and you will get an exception when you try later to access it. This method should only be used if you can guarantee that Offset is equal, for example

 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]; }; 

Please also note that I changed this a bit, so that it immediately returns a 16-bit value, since returning a pointer and then deleting links will most likely be less "efficient" than just returning a 16-bit value directly. I also switched to standard Posix types for integers - I recommend that you do the same.

+7
source

I am surprised that no one has proposed this yet for a solution that is safe and correct alignment in all . (well, any architecture where there are 8 bits per 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 believe that 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 do not throw x86 exceptions. And if I remember, Windows (when it worked on Dec Alpha and others), the trap of eliminating alignment and correction (with a modest performance). And I remember how I found out that Sparc on SunOS just crashed when you had alignment problems.

+4
source

I do not see a problem with this, what exactly will I do. So far, the byte array is safe for access, and you will make sure that the offset is correct (shorts are 2 bytes, so you can make sure that they cannot do odd offsets or something like that)

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

Unfortunately, this is undefined in C ++ because you access the repository using two different types that are not allowed under strict anti-aliasing rules. You can access the type store using char* , but not vice versa.

From the previous questions I asked, the only safe way is to use memcpy to copy bytes to int and then use it. (Most likely, this will be optimized for the same code that you somehow expect, so it just looks inefficient).

Your code will probably work, and most people seem to do it ... But the fact is that you cannot cry to your compiler when one day it generates code that does not do what you hope.

0
source

Yes, this is an effective way, but IMHO it would be better to use a macro.

-2
source

Source: https://habr.com/ru/post/893750/


All Articles