質問

関数ポインターをテンプレートパラメーターとして渡し、インラインドに呼び出しを取得できることは知っていますが、最近のコンパイラが次のような「明白な」インライン可能な関数をインラインできるかどうか疑問に思いました。

inline static void Print()
{
 std::cout << "Hello\n";
}

....

void (*func)() = Print;

func();

Visual Studio 2008では、直接の呼び出し指示に陥るのに十分なほど賢いので、それをさらに一歩進めることができないのは残念です。

役に立ちましたか?

解決

GNUのG ++ 4.5は、最適化レベル-O1から始めて私のためにそれを導入します

main:
    subq    $8, %rsp
    movl    $6, %edx
    movl    $.LC0, %esi
    movl    $_ZSt4cout, %edi
    call    _ZSt16__ostream_insertIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_E
    movl    $0, %eax
    addq    $8, %rsp
    ret

ここで、.lc0は.String "Hello n"です。

最適化なしで、G ++ -O0を比較することは、インラインではありませんでした。

main:
    pushq   %rbp
    movq    %rsp, %rbp
    subq    $16, %rsp
    movq    $_ZL5Printv, -8(%rbp)
    movq    -8(%rbp), %rax
    call    *%rax
    movl    $0, %eax
    leave
    ret

他のヒント

GCC(4.4以降)の新しいリリースには、-findirect -inliningという名前のオプションがあります。 GCCが関数ポインターが一定であることをそれ自体に証明できる場合、関数に直接呼び出されるか、関数を完全に挿入します。

まあ、コンパイラは、その変数がどこかに上書きされるかどうかを本当に知りません(おそらく別のスレッドでは)。

リリースビルドでVS2010をチェックしたばかりで、インラインドされませんでした。

ちなみに、あなたは機能を飾ります inline 役に立たない。標準は、関数のアドレスを取得した場合、 inline ヒントは無視されます。

編集: :ただし、関数がインラインになっていないが、変数はなくなっていることに注意してください。分解で call 直接アドレスを使用しますが、レジスタに変数をロードせず、それを呼び出します。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top