2

std/boost::function に相当するより単純な (より高速な) ものを書いています。私の主な関心事はシンプルさと効率性です。プラットフォームは、gcc と clang でコンパイルされた x86-64 Linux に制限されています。

上記の制限の下で、

  1. すべての関数ポインター、つまり、フリー関数へのポインター、メンバー関数 (POD、仮想メソッドを持つクラス、派生クラス、仮想継承クラスなど)、ファンクター、ラムダなどのサイズはすべて最大で 16 バイトですか?
  2. そして、アライメント要件は何ですか?
4

1 に答える 1

1

x86_64 の場合、関数やメンバーへのポインターは、メンバー関数へのポインターのサイズを超えないと安全に想定できます。GCC の場合sizeof(void*)は 、clang の場合はsizeof(void*)*2(前回チェックしたとき) になります。アラインメント要件は 16 バイトです。GCC を使用すると、__BIGGEST_ALIGNMENT__事前定義されたマクロを利用できます。ただし、clang にはありません。私が提案できる唯一のことは、想定するのではなく、最大サイズを計算するコンパイル時の式を使用することです。

アップデート:

@David が指摘したように、多重および/または仮想継承の場合にメンバー関数呼び出しをディスパッチするには、8 バイトでは不十分な場合があります。したがってsizeof(void*)*2、安全な側にとどまるために、両方の場合に適用されます。

最善の方法は、 を使用したコンパイル時の式のままsizeofです。例えば:

struct Foo {
};

typedef void* (Foo::*pmf)();
typedef void* (*bar)();

constexpr auto max_func_pointer_size() -> decltype(sizeof(void*)) {
    return sizeof(pmf) > sizeof(bar) ? sizeof(pmf) : sizeof(bar);
}

int main()
{
    static_assert(max_func_pointer_size() == 16, "oops!?");
}
于 2013-01-19T03:01:36.200 に答える