1

私が任意の関数を持っていると仮定します:

void someFunc(int, double, char); 

そして私は電話しますsomeFunc(8, 2.4, 'a');、実際に何が起こりますか?8、2.4、および'a'はどのようにしてメモリを取得し、そのメモリに移動して関数に渡されますか?このような状況に対して、コンパイラにはどのような種類の最適化がありますか?次のようなパラメータを組み合わせて使用​​するとどうなりますsomeFunc(myIntVar, 2.4, someChar);か?

関数がとして宣言されている場合はどうなりますinlineか?

4

2 に答える 2

4

値がリテラルであるかどうかに違いはありません(関数がインライン化されていて、コンパイラーがいくつかのものを最適化できる場合を除く)。

通常、パラメーターはレジスターまたは関数パラメーター・スタックに入れられます。それらが明示的な値であるか変数であるかに関係なく。

最適化を行わないと、パラメーターはパラメータースタックにプッシュされます。最初のケースでは、の値がx最初に取得されてレジスタに入れられeax、次にパラメータスタックにプッシュされます。foo印刷しxます。

    foo(x);
00361A75  mov         eax,dword ptr [x] 
00361A78  push        eax  
00361A79  call        get_4 (3612B7h) 
00361A7E  add         esp,4 
    foo(3);
00361A81  push        3    
00361A83  call        get_4 (3612B7h) 
00361A88  add         esp,4 

最適化を使用すると、関数はコンパイラーに表示され(私のサンプルでは)、呼び出しは完全にスキップされます。

    foo(x);
01011000  mov         ecx,dword ptr [__imp_std::cout (101203Ch)] 
01011006  push        3    
01011008  call        dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (1012038h)] 
    foo(3);
0101100E  mov         ecx,dword ptr [__imp_std::cout (101203Ch)] 
01011014  push        3    
01011016  call        dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (1012038h)] 

fooと定義されている:

void foo(int x)
{
   std::cout << x;
}
于 2012-06-11T22:31:28.503 に答える
1

通常、C++ 関数はスタック上で動作します。最適化なしで動作するC 呼び出し規則について説明します。

'a'スタックの一番上に配置されます。次に2.4、スタックの一番上に配置し、次にスタックの一番上に配置8し、戻り値の型[1]用のスペースを追加し、次に呼び出し元関数の現在の命令の命令ポインターを追加してから、呼び出された関数のコード。
呼び出された関数は、スタックを見て、パラメーターを取得し、実行し、結果をスタックに提供されたスペースに入れ、最後にスタックでポイントされている命令にジャンプします (これはおそらく、関数の次の命令です)。と呼んだ)。プロセッサは呼び出し元の関数を再度実行しているため、必要な場所に結果をコピーし、他のすべてのものをスタックからポップします。*

時間を節約するための他の呼び出し規約(その多くはパラメーターをレジスターに保持します) があり、もちろん、例外による複雑な問題が他にもあります。呼び出し元の関数に応じて、リストされているすべての手順をスキップし、呼び出された関数をそれらの定数で直接実行するだけの呼び出しをインライン化するか、非常に高度なコンパイラと特定の条件で、関数のコピーを作成する場合があります。これらのパラメーターがハードコーディングされており、代わりにそのバージョンをパラメーターなしで呼び出します。

私が言ったように、これは私が何年も前に学んだすべての理論です. Luchian Grigore の回答には、きちんとした詳細がたくさんあります。

[1] ウィキペディアによると、結果が single の場合int、スタックではなくレジスタに返されるとのことです。

于 2012-06-11T22:37:31.580 に答える