2012-07-09 13 views
6

私は関数の戻り値を操作する単なる '&'演算子を関数の直後に適用したいと思っています。単項演算子を使用して関数の戻り値を

int function(); 
void function2(int *param); 

main() 
{ 
    function2(&function1()); 
} 

int function1() 
{ 
    return 10; 
} 

void function2(int *param) 
{ 
    return; 
} 

このコードは、同じコンパイル時エラーを生成します。しかし、私は理解することが私の質問を容易にするために、コードを作っ

test.c: In function 'main':

test.c:8:12: error: lvalue required as unary '&' operand

(私はMinGWのからのgccを使用して)コンパイル時エラーを取得します。

質問は: 私は '&'演算子をfunction2 "()"からちょうど他のコードを使わずに使うことができますか?

+2

'function1'が' int'を返す限りは、できません。 – AnT

答えて

11

がC99で、後を介して達成することができる。

function2((int[]){function1()}); 

はつまり文字通りの化合物を作る関数の戻り値を含みます。

+0

これは実際にはかなり賢いです!基本的には、一時的な "匿名"変数を作成し、function1の戻り値に初期化します。 – eresonance

10

できません。関数の戻り値は値ですが、オブジェクトではありません。メモリには指定された場所がなく、アドレスもないため、ポインタを使用することはできません。代わりに、次のように書くことができます:

int a = function1(); 
function2(&a); 
3

問題は、&が変数のアドレスを取ることです。関数の戻り値は、必ずしもメモリに格納されているとは限りません。つまり、lvalueではありません(=の左側に置くことはできません)。したがって、存在しないため、そのアドレスを要求するのは理にかなっていません。

何をすべきことは以下の通りです:6.5.3.2にそれが言う、同じ規格で

An lvalue is an expression (with an object type other than void) that potentially designates an object; (footnote: The name ‘‘lvalue’’ comes originally from the assignment expression E1 = E2, in which the left operand E1 is required to be a (modifiable) lvalue. It is perhaps better considered as representing an object ‘‘locator value’’. What is sometimes called ‘‘rvalue’’ is in this International Standard described as the ‘‘value of an expression’’)

int result = function1(); 
function2(&result); 

C11の標準として6.3.2.1でlvalueを定義します

The operand of the unary & operator shall be either a function designator, the result of a [] or unary * operator, or an lvalue that designates an object that is not a bit-field and is not declared with the register storage-class specifier.

+0

"関数の戻り値が必ずしも変数に格納されているとは限りません"という記述は間違っています。特に "必ずしも必要ではありません"。返される値を格納する変数を指定しない限り、格納されません。 –

+0

@nathanwhite、あなたは正しいです。私はそれを「記憶」に変更しました。 – Shahbaz

2

関数から返される値のアドレスを取得することはできません。

その値がCPUレジスタ経由で呼び出し側に返されるとどうなりますか?

function2()がfunction1()の結果を使用する唯一の方法は、メモリー内にアドレスを持つ中間変数を使用することです。

main() 
{ 
    int a; 

    a = function1(); 
    function2(&a); 
} 
1

これは直接行うことはできません。関数の戻り値は、スタックに格納されていても(すぐに別の関数呼び出しで上書きされます)、レジスタなどに格納されます(呼び出し規約に応じて)。

あなたはおそらくそれらの場所に直接アクセスしたくないし、あまり意味をなさない(まあ、あなたが実際に何をしているのか分からなければ)。

あなたが扱う関数の戻り値は右辺値(まあ単純に値)ですが、 '&'演算子は、コンパイラの出力に見られるように、左辺値に)。 Ergo、戻り値を変数(main()内のローカル変数)に格納してから、そのアドレスを取得してください。何をしたい

int main() { 
    int x = function1(); 
    function2(&x); 
} 
関連する問題