2013-02-26 15 views
7

私がプログラムしている場合:未使用の関数の戻り値はどうなりますか?

#include <iostream> 

using namespace std; 

int TestIntReturn(int &x, int &y) 
{ 
    x = 1000; 
    y = 1000; 
    return x+y; 
} 

int main() 
{ 
    int a = 1; 
    int b = 2; 
    cout << a << " " << b << endl; 
    TestIntReturn(a,b); 
    cout << a << " " << b << endl; 
} 

それが未使用であることからTestInReturn(a,b)の戻り値に何が起こるかを?

+0

あなたの質問には答えられませんが、スタイルに関しては、あなたは 'namespace stdを使用する 'ことを再考したいかもしれません。なぜ、私のコードに「using namespace std」を使用するべきですか?(http://www.parashift.com/c++-faq-lite/using-namespace-std.html) – DavidRR

答えて

8

破棄;式TestInReturn(a,b)は、の廃棄値式です。 intを破棄することは効果がありませんが、volatile int(または他の揮発性修飾されたタイプ)を破棄すると、メモリからの読み取りの影響を受ける可能性があります。

+0

これはどのようにすることができますか?関数の戻り値はrvalueであり、cv-qualificationを持たないことを意味します。クラス型でない限り、 'volatile'(または' const')は無視されます。 –

+0

@JamesKanzeはい。また、関数呼び出しは5p11で左辺値と右辺値の変換を引き起こす式の1つではありません。私は一般的に廃棄された価値のある表現について話していました。 – ecatmur

+0

私はある時点で、これについてC標準委員会で議論していたことを知っています。 i; 'は、2番目のステートメントにアクセスします。私は最後のコンセンサスが何だったのか分かりませんが、先験的に、私はいいえと言います。 –

4

戻り値は単に破棄されます。厳密なシナリオに応じて、オプティマイザは、観察可能な副作用がない場合(例ではそうではない)、関数呼び出し全体を最適化することを決定する場合があります。

したがって、TestIntReturnから戻り値が返されると、呼び出し側はスタックフレームを適切に調整しますが、返された値をスタックからすべての変数にコピーしません。

+0

On戻り値としての 'int'はスタック上のどのアーキテクチャでしょうか?インテルでは、「EAX」になります。 「o0」のSparcで。コードはレジスタの内容を無視します。 –

0

何もない - エーテルに入り、保存されずに使用されます。戻り値自体は右辺値または一時的値です。私はコンパイラが実際に使用されていないために一時的な作成を最適化すると確信しています。

+0

正式な意味論は、完全表現の終わりに一時的に破壊されるということです。テンポラリは関数内で構築され、コールサイトで_destructed_されているため、コンパイラは一時的な機能を削除する機能をインライン化する必要があります。 –

0

戻り値はスタックに格納され、関数が復帰するとポップされます。呼び出し元によって変数に代入されていないので、スタックがポップされたときに破棄されます。

+0

少なくとも "int"型の場合、スタックに戻り値を格納するアーキテクチャはごくわずかです。 –

11

Windowsについては、x86プロセッサを想定しています。

この場合、戻り値は通常EAXレジスタになります。あなたはそれを使用していないので、その値は無視され、次にEAXに何かを書き込むコードが実行されたときに上書きされます。

かなりの場合、関数が他の副作用を持たない場合(単に入力を受け取り、何らかの結果を返す)、コンパイラは結果を使用していないときを把握し、関数。

あなたのケースでは、この関数にはいくつかの副作用がありますので、それらの副作用を実行する必要がありますが、合計を計算するコードを削除する可能性があります。たとえそれが省略されていなくても、実際に追加されるものは実際には2つの定数であることが分かります。したがって、実行時に実際に結果を計算することはありません。mov EAX, 2000戻り値

0

誰もが正しく答えました - この場合の戻り値は単に破棄され、この具体例では無視できます。戻り値は、関数の内部で割り当てられたメモリへのポインタである、そしてあなたはそれを無視した場合、あなたは単に無視しますが、中にすることはできませんmemory leak.

だから、いくつかの関数の値を持っています

しかし、この場合 - できます。

+0

オブジェクトへのポインタのタイプによっては、オブジェクトを無視することもできます。私はコンストラクタがそのオブジェクトを辞書に登録したオブジェクトを使用しました。そのオブジェクトは後で見つけることができます。一方、戻り値がスマートポインタまたは他のクラス型の場合、そのデストラクタが呼び出されます。 –

0

プリミティブ型の場合は、何も起こりません。それはちょうど無視された です。クラス型の場合、返されたオブジェクト は何も起こらずに破棄されます。

関連する問題