paIncrease
paIncrease

Reputation: 465

overcoming little-endian-ness when union'ing char[4] with int32

On my little-endian z80-esque processor I have a 32-bit long int msk = 0xFFFFFF00 (Subnet Mask). I learned about endian-ness this morning when I tried passing (unsigned char *)&msk to a void bar(unsigned char * c); function that walks through the values of this &msk and stores them to a database.

Unfortunately due to the little-endian-ness of z80 processors, the database stores the values "backwards", and when another function reads the bytes back, it sees 0x00FFFFFF, which is not the correct subnet mask.

Is there any trivial way around this with unions? I'd like char[3] to map to the LSB of my long int msk, instead of what it currently is (char[0] gets the LSB).

In conclusion, Big-Endian is better.

Upvotes: 0

Views: 841

Answers (2)

asbumste
asbumste

Reputation: 451

ntohl will swap the endianess of a 32-bit integer

Upvotes: 1

Zan Lynx
Zan Lynx

Reputation: 54355

To fix endian issues: Whenever you serialize your integers to disk or to the network, convert them to a known byte order. Network order aka big-endian, is the easiest because the htonl and htons functions already exist. Or you may do it manually by repeatedly pulling off the low-order byte with byte & 0xFF; byte >>= 8 or the high-order byte with ((byte >> i*8) & 0xFF)

If you have a long int value and want the LSB of it, it is far more portable to use bit shift and mask operations rather than unions or casts.

Upvotes: 2

Related Questions