16

だから、私はここで同様の質問を見つけましたが、答えはスタイルとあなたがそれを行うことができるかどうかに関するものです.

私の質問は、オブジェクトを返す非 void 関数を呼び出すと実際に何が起こるかということですが、返されたオブジェクトを割り当てたり使用したりすることはありませんか? だから、あなたができるかどうかについてはあまり言いません。私はあなたができることを絶対に知っていて、上にリンクされた他の質問を理解しているからです.コンパイラ/ランタイム環境は何をしますか?

これは言語固有の質問ではありませんが、回答する場合は、動作が異なるため、どの言語について言及しているのかを明記してください。

4

5 に答える 5

17

C# と Java の両方で、結果は最終的にスタックに置かれ、コンパイラは pop 命令を強制的に無視させると思います。「The void is invariant」に関する Eric Lippert のブログ投稿には、これに関する詳細情報があります。

たとえば、次の C# コードについて考えてみます。

using System;

public class Test 
{
    static int Foo() { return 10; }
    
    public static void Main()
    {
        Foo();
        Foo();
    }
}

Mainメソッドに対して (MS C# 4 コンパイラによって) 生成される ILは次のとおりです。

.method public hidebysig static void Main() cil managed
{
    .entrypoint
    .maxstack 8
    L_0000: call int32 Test::Foo()
    L_0005: pop 
    L_0006: call int32 Test::Foo()
    L_000b: pop 
    L_000c: ret 
}

-への呼び出しに注意してください。これは、void メソッドpopを作成すると消えます。Foo

于 2010-10-22T15:31:39.500 に答える
7

コンパイラは何をしますか?

コンパイラは、結果を仮想スタックから破棄する pop 命令を生成します。

ランタイム環境は何をしますか?

通常、スタックの場所ではなく、戻り値をレジスタに戻すコードにコードを jit します。(通常、x86 アーキテクチャでは EAX です。)

ジッタは、値が使用されないことを認識しているため、おそらくレジスタをクリアするコードを生成します。または、レジスターにしばらくぶら下がっているだけかもしれません。

どのランタイム環境が気になりますか? それらはたくさんあり、それらはすべて異なるジッターを持っています。

于 2010-10-22T18:42:39.577 に答える
3

使用されている呼び出し規約に少し依存します。小さい/単純な型の場合、戻りは通常レジスタで発生します。この場合、関数は値をレジスタに書き込みますが、他に注意を払うことはなく、次にそのレジスタが必要になったときに (通常はすぐに発生します)、別のもので上書きされます。

より大きな型の場合、コンパイラは通常、戻り値を保持する構造を割り当てます。ただし、その割り当てが正確にどこでどのように行われるかは、コンパイラによって異なります。場合によっては、静的構造になり、同じ型を返す関数を次に呼び出すときに内容が無視され、上書きされます。それ以外の場合はスタック上にあり、使用していなくても、関数が呼び出される前に割り当てられ、後で解放される必要があります

于 2010-10-22T15:37:45.733 に答える
1

.NET では、返されるオブジェクトが参照型であり、アプリケーションがそのオブジェクトへの他の参照を持たない場合、ガベージ コレクターがオブジェクトを収集することを決定するまで、オブジェクトがメモリ内に浮遊したままになります。

返されるオブジェクトがたまたまリソースを保持している場合、これは潜在的に悪いことです。インターフェイスが実装されている場合IDisposable、コードで Dispose メソッドを呼び出す必要がありますが、この場合、Dispose メソッドは呼び出されません。

編集:タイプミスを修正しました。

于 2010-10-22T16:40:25.123 に答える
1

C++ の場合、通常、コンパイラは変数の戻り値を最適化して void 関数に変換します。これによりさらに最適化が可能になる場合、コンパイラは関数呼び出し全体または戻り値のみに関係する部分を最適化する可能性があります。 . Java と C# については、ほとんどわかりません。

于 2010-10-22T16:40:29.490 に答える