2012-07-09 9 views
6

Chciałem zastosować jednoargumentowy operator "&" tuż za funkcją, aby działać na funkcji zwracanej wartości. Jednakże pojawia się błąd kompilacji (używam gcc z MinGW)przy użyciu operatora unarnego i operatora zwracającego wartość funkcji

test.c: In function 'main':

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

Zrobiłem kod aby moje pytanie łatwiej zrozumieć:

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

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

int function1() 
{ 
    return 10; 
} 

void function2(int *param) 
{ 
    return; 
} 

Ten kod tworzy sam błąd kompilacji .

Pytanie brzmi: Jak mogę korzystać z operatora "&" tylko od funkcji2 "()", bez żadnego innego kodu?

+2

Nie można, dopóki 'funkcja1' zwraca' int'. – AnT

Odpowiedz

11

Co chcesz można osiągnąć na C99 i później poprzez:

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

tj wytwarzania związku zawierającego dosłowne wartości zwracanej przez funkcję.

+0

To jest całkiem sprytne! Zasadniczo tworzy tymczasową zmienną "anonimową" i inicjuje ją do wartości zwracanej funkcji 1. – eresonance

10

Nie możesz. Zwracana wartość funkcji jest wartością, ale nie obiektem. Nie ma wyznaczonej lokalizacji w pamięci, nie ma adresu, więc nie można zająć wskaźnika. Zamiast tego możesz napisać:

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

Problem polega na tym, że & przyjmuje adres zmiennych. Wartość zwracana funkcji niekoniecznie jest zapisywana w pamięci. Innymi słowy, nie jest to lvalue (nie można go umieścić po lewej stronie =). Dlatego nie ma sensu pytać o jego adres (ponieważ nie istnieje).

Co należy zrobić, jest następujący:

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

Standard C11 określa lvalue w 6.3.2.1 jako:

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

W tym samym standardzie, w 6.5.3.2 mówi:

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

Podanie "Zwracana wartość funkcji niekoniecznie jest zapisana w zmiennej" jest nieprawidłowe, w szczególności "niekoniecznie". Dopóki nie określisz zmiennej dla zwróconej wartości, która ma zostać zapisana, NIE zostanie ona zapisana. –

+0

@ nathanwhite, masz rację. Zmieniłem go na "pamięć". – Shahbaz

2

Nie można uzyskać adresu wartości zwracanej przez funkcję.

Co się stanie, jeśli ta wartość zostanie przekazana dzwoniącemu przez rejestr CPU?

Jedynym sposobem, aby funkcja 2() wykorzystywała wynik funkcji1(), jest użycie zmiennej pośredniej, która ma adres w pamięci.

main() 
{ 
    int a; 

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

Nie możesz tego zrobić bezpośrednio. Wartość zwracana przez funkcję może być przechowywana na stosie (i wkrótce zostanie nadpisana w innym wywołaniu funkcji), lub może w rejestrach itp. (W zależności od konwencji wywoływania).

Prawdopodobnie nie chcesz mieć bezpośredniego dostępu do żadnego z tych miejsc i nie ma to większego sensu (no, może, jeśli nie wiesz, co robisz).

Wartością zwracaną przez funkcję, z którą pracujesz, jest wartość r (po prostu ... po prostu wartość), podczas gdy operator "&" potrzebuje, jak widzisz na wyjściu kompilatora, wartości l (coś, co możesz przypisać do). Ergo, po prostu przechowuj wartość zwracaną w zmiennej (zmienna lokalna w twoim "main()", a następnie uzyskaj jej adres).

int main() { 
    int x = function1(); 
    function2(&x); 
} 
Powiązane problemy