1

たとえば、32ビット値のバイトを交換する関数があるとします。

uint32_t byte_swap(uint32_t in);

その32ビット値をスタックにプッシュして再度ポップするのはばかげているようです。特にこの関数を頻繁に呼び出す場合は、ECXを介して渡します。

#if __FASTCALL_SUPPORTED_   /* Whatever this may be */
#define FASTCALL __attribute__((fastcall))
#else
#define FASTCALL
#endif

uint32_t FASTCALL byte_swap(uint32_t in);

今私の質問は、その関数を配布用の共有ライブラリにコンパイルしても安全ですか?ユーザーが別のコンパイラを使用してプログラムとこれに対するリンクをコンパイルした場合でも、関数は正しく呼び出されますか?

4

1 に答える 1

4

__attribute__((fastcall))gcc拡張です。そのため、呼び出し元がgccも使用していない場合は、使用できない可能性があります。さらに、提供したサンプルでは、​​__ FASTCALL_SUPPORTED_が定義されていない場合、間違った呼び出し規約で呼び出しが発生することになります。これは悪い考えです。

これに対処する1つの方法は、フォールバックラッパーを使用することです。.cファイル内:

#include "foo.h"

uint32_t FASTCALL byte_swap(uint32_t in) {
    /* code ... */
}

uint32_t byte_swap__slowcall(uint32_t in) {
    return byte_swap(in);
}

そしてあなたの.hファイルで:

#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);

また、Linuxでは、高速のbyteswap実装が<byteswap.h>として利用可能であることに注意してくださいbswap_32。x86マシンでは、インラインアセンブラにコンパイルされ、十分に高い-march=設定で1つの命令が実行されます。

于 2009-09-27T21:42:44.380 に答える