C++: Unsigned Char to unsigned int using pointers without bit shifts

  • A+
Category:Languages

Suppose I have a C-style array of type unsigned char:

unsigned char * c = (unsigned char *) malloc(5000 * sizeof(unsigned char)); for(int i = 0; i < 5000; i++)      c[i] = (unsigned char) ((i >> (i%4 * 8)) & 0xFF); 

Suppose I have a pointer offset to a position which starts a 4 byte integer:

// pseudo code unsigned int i = c + 10; // 10 = pointer offset, let's say.  

If I want to load i up with the correct number, I can do:

unsigned int i = (*(c+10) << 24) + (*(c+11) << 16) + (*(c+12) << 8) + (*(c+13)); 

But shouldn't I just be able to, somehow, do this using casts?

// pseudo code -- I haven't gotten this to work yet:   int i = (unsigned int) (*((void *)(c+10));  // or maybe int i = *((unsigned int*)((void *)(c+10))); 

In short, what is the cleanest, most effective way to transition the four bytes to an unsigned int in a C-style byte array?

 


The proper way to do this is to use memcpy:

unsigned int i; std::memcpy(&i, c + offset, sizeof(unsigned int)); 

On architectures that support unaligned variable access (like x86-64), this will be optimized into a simple pointer dereference, but on systems that don't support unaligned access (such as ARM), it will do the proper thing to get the value out.

See for example: https://gcc.godbolt.org/z/l5Px4G . Switch the compiler between gcc for x86 and arm and see the difference in instructions.

Keep in mind the idea of endianness if you're getting the data from some external source. You may have to flip the bytes of the integer around for the value to make sense.

Comment

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: