2

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

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

....

void (*func)() = Print;

func();

Visual Studio 2008 では、それを直接呼び出し命令に落とし込むのに十分なほど巧妙なので、さらに一歩進めることができないのは残念ですか?

4

3 に答える 3

4

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

于 2010-06-02T17:01:37.883 に答える
2

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
于 2010-06-02T17:00:54.797 に答える
1

コンパイラは、その変数がどこかで(おそらく別のスレッドで)上書きされるかどうかを実際には知らないため、注意してエラーを起こし、関数呼び出しとして実装します。

リリース ビルドで VS2010 をチェックインしたところ、インライン化されませんでした。

ちなみに、関数をそのまま飾ってinlineもダメです。標準では、関数のアドレスを取得した場合、inlineヒントは無視されるとされています。

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

于 2010-06-02T16:24:35.447 に答える