Can anyone tell me what's the difference between __bswap_constant_XX
and __bswap_XX
also when to prefer one over another?
I am using GCC 4.8
Can anyone tell me what's the difference between __bswap_constant_XX
and __bswap_XX
also when to prefer one over another?
I am using GCC 4.8
First of all, you should not normally use symbols with double underscores as those are reserved.
Symbols you are talking about are not compiler-defined, but a part of your C library. bswap_XX
macros can use compiler intrinsic or even inline assembly to make compiler generate cpu-specific instructions, making the result unknown at compilation time.
In contrast, __bswap_constant_XX
are supposed to evaluate the value using simple C expressions, making value compile-time constant if the input is a compile-time constant.
Such macros can be defined as:
#define __bswap_constant_16(x) \
((__uint16_t) ((((x) >> 8) & 0xff) | (((x) & 0xff) << 8)))
#define __bswap_constant_32(x) \
((((x) & 0xff000000u) >> 24) | (((x) & 0x00ff0000u) >> 8) | \
(((x) & 0x0000ff00u) << 8) | (((x) & 0x000000ffu) << 24))
The idea is that you should use __bswap_constant_XX
when you need compile-time value, for example when defining enum value:
enum myenum {
MYVALUE = __bswap_constant_16(0x1234)
};
bswap_XX
is supposed to be used in all other cases.
Note that modern compiler are able to recognize simple byte-swap patterns and generate appropriate instructions, so in practice this won't make a difference most of the time.
For example for both functions:
uint16_t bswap16(uint16_t x)
{
return __bswap_constant_16(x);
}
uint32_t bswap32(uint32_t x)
{
return __bswap_constant_32(x);
}
GCC 4.8.1 generates:
bswap16:
mov eax, edi
rol ax, 8
ret
bswap32:
mov eax, edi
bswap eax
ret