Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C/pre-processor: detect if a __builtin function is available

Is it possible to somehow determine whether an intrinsic function, such as __builtin_bswap16 is provided by the compiler? Preferably, I would like to be able to determine whether this function exists using just preprocessor.

In my particular case, I was using __builtin_bswap16 / 32 / 64 functions in my code which worked fine with GCC 4.x when compiling for 32-bit. Later I switched to a 64-bit Linux and noticed that __builtin_bswap16 suddenly disappeared - I received a linker error:

"undefined reference to `__builtin_bswap16'".

I guess this has something to do with the availability of certain ASM operations in 64-bit mode.

On a later occasion I was trying to compile this code on a different machine where unfortunately only an older version of GCC is installed and does not support these functions at all.

I would like to make this code compilable everywhere, using __builtin_bswap functions if provided, and fall back to hand-coded byteswap routine if not. Is it possible to achieve this somehow with just preprocessor?

My obvious attempt, e.g.:

...
#define MYBSWAP16(v) (v>>8)|(v<<8)
#ifdef __builtin_bswap16
printf("bswap16 is defined : %04x\n", __builtin_bswap16(0x1234));
#else
printf("bswap16 is not defined : %04x\n", MYBSWAP16(0x1234) );
#endif
...

was not successful, as __builtin_bswap16/32/64 are always evaluated to be undefined. Is there any way to make it work automatically within the C source, or is the only way to manually define constants in the Makefile, e.g. HAVE_BSWAP and pass them via -D option?

Please note that my question is not necessarily specific to __builtin_bswap, I'm looking for a general way to detect if the certain functions are available.

like image 798
Angro Avatar asked Aug 13 '13 12:08

Angro


2 Answers

Unavailability of __builtin_bswap16 is a gcc bug which was fixed in gcc 4.8.

like image 119
Marat Dukhan Avatar answered Oct 30 '22 15:10

Marat Dukhan


Sincw it is missing from some versions of gcc you can always add it to your code yourself :

static inline unsigned short __builtin_bswap16(unsigned short a)
{
    return (a<<8)|(a>>8);
}
like image 30
such_code_much_logic Avatar answered Oct 30 '22 13:10

such_code_much_logic