2

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…

Community
  • 1
  • 1
Marnix
  • 59
  • 6

0 Answers0