私は主にC#を使って開発していますが、この質問は他の言語にも適していると思います。
また、ここにはたくさんのコードがあるようですが、質問は非常に簡単です。絶対リターンパスを持つメソッドはどのようにインライン化されますか?
私が理解するように、インライン展開は、メソッドが呼び出されたすべての場所にメソッドの本体を挿入することによって、メソッド呼び出しを置き換えるコンパイラ(C#仮想マシンの場合)です。
のは、私は次のプログラムがあるとしましょう:私はコードがメソッドをインライン展開した後、次のようになりますどのように理解することができ
bool IsEven(int n)
{
if (n % 2 == 0) // Two conditional return paths
return true;
else
return false;
}
:メソッドIsEven
のボディ...
static Main()
{
int number = 7;
bool a;
a = IsEven(number);
Console.WriteLine(a);
}
を
static Main()
{
int number = 7;
bool a;
if (number % 2 == 0)
a = true;
else
a = false;
Console.WriteLine(a); // Will print true if 'number' is even, otherwise false
}
明らかに単純で正しいプログラムです。
しかし、私は絶対リターンパスを含めるようにIsEven
の身体を少し微調整であれば...
bool IsEven(int n)
{
if (n % 2 == 0)
return true;
return false; // <- Absolute return path!
}
私個人的には、いくつかの状況で、もう少しこのスタイルのように。一部の屈折工具は、私がこのように見えるように最初のバージョンを変更することを示唆するかもしれませんが、インラインでどのように見えるか想像してみると、私は困惑しました。
static Main()
{
int number = 7;
bool a;
if (number % 2 == 0)
a = true;
a = false;
Console.WriteLine(a); // Will always print false!
}
質問頼まれる:
我々は方法の第二のバージョンをインライン化した場合
はどのように絶対リターンパスを持つメソッドをインライン化するとコンパイラ/仮想マシンの契約?
このようなことでメソッドのインライン展開が実際に妨げられることはほとんどないようです。そのようなことがどう対処されているのだろうかと思います。おそらく、インライン展開のプロセスはこれほど簡単ではありませんか?おそらく1つのバージョンがVMによってインライン化される可能性が高いでしょうか?
編集: は両方の方法(および最初のものを手動でインライン化)をプロファイリング少なくとも私に(同じまたは類似の方法で性能に差を示さなかったので、私は唯一の両方の方法は、インライン化を受けることを想定することができ、作業VM)。
また、これらのメソッドは非常に単純でほとんど互換性があるようですが、絶対リターンパスを持つ複雑なメソッドは絶対リターンパスを持たないバージョンに変更するのがはるかに難しいかもしれません。
btw:このwhile(true)breakのメカニズムは、他のものにも便利です。私は頻繁には使用しませんが、必要に応じて実行する必要がある一連の操作いつでも停止しておくと便利です。同様に、ネイティブ言語では、「最終的に」コンストラクタを持っていないときにそれをシミュレートするために使用されます(私はそれをいくつかのプロジェクトでかなり使いました) –