Is it safe to use fastcall in a shared library?
Question
For example, let's say I have a function that will swap bytes in a 32 bit value for you:
uint32_t byte_swap(uint32_t in);
Well it seems silly to push that 32-bit value onto the stack and pop it off again, especially if we're going to be calling this function a lot, so let's pass it in through ECX:
#if __FASTCALL_SUPPORTED_ /* Whatever this may be */
#define FASTCALL __attribute__((fastcall))
#else
#define FASTCALL
#endif
uint32_t FASTCALL byte_swap(uint32_t in);
Now my question is, is it safe to compile that function into a shared library for distribution? If the user uses a different compiler to compile their program and links against this, will the function still be called properly?
Solution
__attribute__((fastcall))
is a gcc extension; as such, it may not be usable if the caller is not using gcc as well. Moreover, in the sample you gave, if __FASTCALL_SUPPORTED_ is not defined, you'll end up with a call with the wrong calling convention - bad idea.
One way to deal with this may be using a fallback wrapper. In your .c file:
#include "foo.h"
uint32_t FASTCALL byte_swap(uint32_t in) {
/* code ... */
}
uint32_t byte_swap__slowcall(uint32_t in) {
return byte_swap(in);
}
And in your .h file:
#if __FASTCALL_SUPPORTED_ /* Whatever this may be */
#define FASTCALL __attribute__((fastcall))
#else
#define FASTCALL
#define byte_swap byte_swap__slowcall
#endif
uint32_t FASTCALL byte_swap(uint32_t in);
Also, note that on Linux, a fast byteswap implementation is available in <byteswap.h>
as bswap_32
. On x86 machines, it will compile down to inline assembler, and a single instruction on high enough -march=
settings.