views:

139

answers:

1

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?

+4  A: 

__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.

bdonlan