2012-07-09 15 views
6

Ich wollte unäre "&" -Operator direkt hinter Funktion anwenden, um auf Funktionsrückgabewert zu arbeiten. Allerdings habe ich einen Fehler bei der Kompilierung bekommen (ich benutze gcc von MinGW)mit unary & Operator auf Funktion Rückgabewert

test.c: In function 'main':

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

ich einen Code gemacht auf meine Frage leichter verständlich zu machen:

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

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

int function1() 
{ 
    return 10; 
} 

void function2(int *param) 
{ 
    return; 
} 

Dieser Code erstellt gleichen Fehler bei der Kompilierung .

Die Frage ist: Wie kann ich den '&' Operator nur von Funktion2 "()", ohne anderen Code woanders?

+2

Sie können nicht, solange 'function1' ein' int' zurückgibt. – AnT

Antwort

11

Was Sie wollen, können in C99 erreicht werden und später über:

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

das heißt Herstellung einer Verbindung wörtliche die Funktion Rückgabewert enthält.

+0

Das ist eigentlich ziemlich clever! Im Wesentlichen erstellt eine temporäre "anonyme" Variable und initialisiert es auf den Rückgabewert von Funktion1. – eresonance

10

Sie können nicht. Der Rückgabewert einer Funktion ist ein Wert, aber kein Objekt. Es hat keinen bestimmten Speicherort im Speicher, keine Adresse, und daher können Sie keinen Zeiger darauf nehmen. Stattdessen könnten Sie schreiben:

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

Das Problem ist, dass & die Adresse von Variablen erfolgt. Der Rückgabewert einer Funktion wird nicht notwendigerweise im Speicher gespeichert. Mit anderen Worten, es ist kein lvalue (Sie können es nicht auf die linke Seite von = setzen). Daher ist es nicht sinnvoll, nach seiner Adresse zu fragen (weil sie nicht existiert).

Was sollten Sie tun, ist die folgende:

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

Der C11-Standard definiert lvalue in 6.3.2.1 als:

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’’)

Im gleichen Standard in 6.5.3.2 heißt es:

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

Die Angabe "Der Rückgabewert einer Funktion ist nicht unbedingt in einer Variablen gespeichert" ist falsch, speziell "ist nicht notwendig". Sofern Sie keine Variable für den zurückgegebenen Wert angeben, in der sie gespeichert werden soll, wird sie NICHT gespeichert. –

+0

@nathanwhite, Sie haben Recht. Ich habe es in "Erinnerung" geändert. – Shahbaz

2

Sie können die Adresse eines von einer Funktion zurückgegebenen Werts nicht abrufen.

Was passiert, wenn dieser Wert über ein CPU-Register an den Aufrufer zurückgegeben wird?

Die einzige Möglichkeit, Funktion2() das Ergebnis von function1() zu verwenden, besteht darin, eine Zwischenvariable zu verwenden, die zufällig eine Adresse im Speicher hat.

main() 
{ 
    int a; 

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

Sie können dies nicht direkt tun. Der Funktionsrückgabewert kann auf dem Stapel gespeichert werden (und wird bald in einem anderen Funktionsaufruf überschrieben werden) oder möglicherweise in den Registern usw. (abhängig von der Aufrufkonvention).

Sie wollen wahrscheinlich nicht direkt auf einen dieser Orte zugreifen und es macht nicht einmal viel Sinn (gut, vielleicht, wenn Sie nicht wissen, was Sie tun).

Der Rückgabewert einer Funktion, mit der Sie arbeiten, ist ein rvalue (naja ... einfach ein Wert), während der '&' Operator, wie Sie in der Compilerausgabe gesehen haben, einen Lvalue benötigt zu). Ergo, speichern Sie einfach den Rückgabewert in einer Variablen (eine lokale Variable in Ihrem 'main()', dann erhalten Sie die Adresse davon).

int main() { 
    int x = function1(); 
    function2(&x); 
}