I’m trying to understand following platform independent htonl() code:
uint32_t htonl(uint32_t val)
{
uint8_t v[4];
uint32_t *result = (uint32_t *)v;
int i;
for (i=0; i<4; i++) {
v[i] = (uint8_t)(val >> ((3-i) * 8));
}
return *result;
}
I made up an example and hope someone can confirm my assumptions are correct.
Suppose we have 0x 4A 3B 2C 1D at address 100. On a BE machine it would look like
Adress: Byte value
100: 4A
101: 3B
102: 2C
103: 1D
On an LE machine it would look like
Adress: Byte value
100: 1D
101: 2C
102: 3B
103: 4A
Now we call htonl() and store the result from address 500
On BE:
Adress: Byte value
500: 4A
501: 3B
502: 2C
503: 1D
On LE:
Address: Byte value
500: 4A
501: 3B
502: 2C
503: 1D
So calling htonl() for BE had no net effect and for LE reversed the byte order.
Now for the htonl() code. Let’s take the first iteration (i=0) from the for –loop.
My assumptions are:
For a BE system:
(uint8_t)(val >> 24) will shift the byte with value 4A from address 100 to >address 103
V[0] is address 500
For an LE system:
(uint8_t)(val >> 24) will shift the byte with value 4A from address 103 to address 100 (so from a BE perspective this would be a left shift).
V[0] is address 500 – this works because v[8] is uint8_t. If v would be uint64_t then v[0] would be address 503 and htonl() would have no effect for LE either.
With these assumptions I can understand what’s happening, but are my assumptions correct?
Thanks for reading…