Except it is. On x86, which is little endian, compilers are smart enough to convert it to a mov.
> These functions will either swap, or not, depending on the endianness of the target machine
So will the above. Here's the MIPS little endian version:
read_int32(unsigned char*):
lwl $2,3($4)
j $31
lwr $2,0($4)
This doesn't swap. The MIPS big endian version: read_int32(unsigned char*):
lbu $3,1($4)
lbu $2,2($4)
sll $5,$3,8
lbu $6,0($4)
sll $3,$2,16
lbu $2,3($4)
or $3,$5,$3
or $3,$3,$6
sll $2,$2,24
j $31
or $2,$3,$2
This swaps and ors. What part of this do you not consider portable between different-endian machines?But it is. That's the whole point, to not bother with weird endian conversion macros.
You're telling me that what the linux kernel guys do is "weird endian conversion macros?" I don't believe you.
It doesn't always swap. Look at the assembly I posted above comparing mips64le to mips64be.
The code takes the byte at b[n] and shifts it (8.n)-bits. These are the same bytes on both little endian and big endian machines. They read the bytes in the same order (little endian), and convert them to the native order.
You can also see very clearly that it doesn't always swap by looking at the simple x86_64 assembly output that the was posted where no shifts or swaps are performed. Just a mov instruction.
Read the assembly. Or better yet, try the code out for yourself.
Assuming LE ordering on the writer side, you would need to swap again on a BE machine. Usually, however, you want to store in your target byte order, though. One could argue this is irrelevant as long as the memory doesn't leave your application, of course. Yet, by explicitly having macros _to_cpu, _to_be, _to_le and so on you make all of this explicit.
These functions will either swap, or not, depending on the endianness of the target machine, and this decision is made at compile time, so the "no swap" case imposes no performance penalty.)
That way, the intent is clear, and the code works on big endian and little endian. So instead of what you propose, which I imagine you might use via:
you'd have: Now the intent is clear, and the code is portable, x is big endian, and we want native CPU (whether that be big endian or little endian).Likewise, you could write:
say before writing it out to disk or network for some purpose that requires big endian.This is similar to htonl(), ntoh(), htons(), ntohs(). (host to network/network to host long/short).