split 32 bit variable to array of 4 u8 variables

Hello.

How can I split (using pointers) u32 variable to array of 4 u8 ?

I tried this:

1
2
u32 data = 0x12345678;
u8 * data_8_bit = (u8*)&data;

But seems to fail.
Do I need to define data_8_bit as array of 4 first?

Bit shifting and AND masks. Super common thing to do. Very easy.

Don’t just cast unless you have already accounted for endianness issues.

1
2
3
4
5
6
7
void u32_to_u8_4( u32 value, u8 array[4] )
{
  array[0] = u32 >> 24; // no need for & 0xFF because target is BYTE
  array[1] = u32 >> 16;
  array[2] = u32 >>  8;
  array[3] = u32 >>  0;
}

I assume u32 and u8 are both unsigned. If not, they should be, or your results will not be what you think they ought to be.

Enjoy! :O)
Thanks
Yes they are unsigned

But does my suggested solution is correct?
No. Don’t cast unless you have already accounted for endianness issues.

Also, don’t cast unless you can do the proper end-run around your compiler’s strict language standards checking — C++ doesn’t want you to do that, because it’s dangerous code. IDR whether it is technically UB or not. (It probably is.)
apart from endianness, which simply makes the bytes not where you might think they would be in the array indexing, its fine. You can do a one time (per execution) test to see which endian your machine is and proceed as necessary from that knowledge. Its not different than casting it to a char* to use it with a binary file write or similar commonly done pointer magic operations.

But seems to fail.

be very specific or show your code.
try printing it in [3][2][1][0] order and see if you get your 123456 back... that is the endian issue, you were getting 56 34 12 probably?

this works fine here in the forum compiler thingy.
1
2
3
4
5
6
7
8
#include <cstdio>
using namespace std;
int main()
{
  uint32_t x{0x12345678};
  uint8_t* px = (uint8_t*)(&x);
 printf("%x%x%x%x\n", px[3],px[2],px[1],px[0]);
}
Last edited on
Heh, I was wrong (in this specific instance, lol).

Here’s a pretty good overview of “type punning”, with links to details for the curious:
https://tttapa.github.io/Pages/Programming/Cpp/Practices/type-punning.html

Take note that it C++ specifically indicates this is a one-way operation.


All that said, you can generally get away with it —I have— but again, know your compiler and know your target architecture, otherwise all bets are off. UB is not your friend.
For the cast to be correct, u8 must be another name for unsigned char or char or std::byte. It can't be anything else. In particular it can't be char8_t.

In my opinion u8 should not be std::uint8_t either, since the implementation has freedom to define it as something besides one of the acceptable types. See this:
https://cplusplus.com/forum/general/284814/#msg1234780
Last edited on
Topic archived. No new replies allowed.