1

インライン関数はパラメーターのコピーにスタックを使用しないことを知っていますが、呼び出された関数の本体を置き換えるだけです。

次の 2 つの関数を検討してください。

inline void add(int a) {
   a++; 
} // does nothing, a won't be changed
inline void add(int &a) {
   a++; 
} // changes the value of a

パラメータの送信にスタックが使用されない場合、コンパイラは変数が変更されるかどうかをどのように認識しますか? これら 2 つの関数の呼び出しを置き換えると、コードはどのようになりますか?

4

4 に答える 4

0

メソッドをインライン化するように強制した場合、少なくともGCCがそれに対して何をするかを確認しました。

inline static void add1(int a) __attribute__((always_inline)); 
void add1(int a) {
   a++; 
} // does nothing, a won't be changed

inline static void add2(int &a) __attribute__((always_inline));
void add2(int &a) {
   a++; 
} // changes the value of a

int main() {

label1:
    int b = 0;
    add1(b);

label2:
    int a = 0;
    add2(a);

    return 0;
}

このアセンブリ出力は次のようになります。

.file   "test.cpp"
.text
.globl  main
.type   main, @function
main:
.LFB2:
    .cfi_startproc
    pushl   %ebp
    .cfi_def_cfa_offset 8
    .cfi_offset 5, -8
    movl    %esp, %ebp
    .cfi_def_cfa_register 5
    subl    $16, %esp
.L2:
    movl    $0, -4(%ebp)
    movl    -4(%ebp), %eax
    movl    %eax, -8(%ebp)
    addl    $1, -8(%ebp)
.L3:
    movl    $0, -12(%ebp)
    movl    -12(%ebp), %eax
    addl    $1, %eax
    movl    %eax, -12(%ebp)
    movl    $0, %eax
    leave
    .cfi_restore 5
    .cfi_def_cfa 4, 4
    ret
    .cfi_endproc
.LFE2:

興味深いことに、その最初の呼び出しでさえ、add1()結果として関数呼び出しの外部で効果的に何も実行せず、最適化されていません。

于 2013-10-27T13:35:31.833 に答える
0

スタックがあると思う理由は何ですか? たとえあったとしても、それがパラメーターを渡すために使用されると思う理由は何ですか?

推論には 2 つのレベルがあることを理解する必要があります。

  • 言語レベル: 起こるべきことのセマンティクスが定義されている場所
  • マシンレベル:CPU命令にエンコードされたセマンティクスが実行される場所

言語レベルでは、const 以外の参照でパラメーターを渡すと、関数によって変更される可能性があります。言語レベルは、この不思議な「スタック」が何であるかを知りません。注: このinlineキーワードは、関数呼び出しがインライン化されているかどうかにほとんどまたはまったく影響を与えません。定義がインライン化されていることを示すだけです。

マシンレベルでは...これを達成する方法はたくさんあります。関数呼び出しを行うときは、呼び出し規約に従う必要があります。この規則は、呼び出し元と呼び出し先の間で関数パラメーター (および戻り値の型) がどのように交換されるか、およびその中で誰が CPU レジスターの保存/復元を担当するかを定義します。一般に、これは非常に低レベルであるため、この規則は CPU ファミリごとに異なります。

たとえば、x86 では、いくつかのパラメーターが CPU レジスターに直接渡され (適合する場合)、残りのパラメーター (存在する場合) はスタックに渡されます。

于 2013-10-27T13:21:55.363 に答える