2013-06-11 7 views
9

Napisałem funkcję, która zwraca odniesienie do lokalnego obiektu.Funkcja, która zwraca odniesienie do lokalnego obiektu

Fraction& operator*(Fraction& lhs, Fraction& rhs) 
{ 
    Fraction res(lhs.num*rhs.num,lhs.den*rhs.den); 
    return res; 
} 

Po funkcji powrotu res obiekt zostanie zniszczony i odbierania obiekt będzie wskazywać na przedmiot Przykład frakcji prowadzi do nieokreślonego zachowania jego używania. Każdy, kto zamierza skorzystać z tej funkcji, napotka problem.

Dlaczego kompilator nie może wykryć takiej sytuacji jako błędu czasu kompilacji?

+13

Ogólnie może - g ++ wypisuje coś w rodzaju 'ostrzeżenie: odwołanie do zmiennej lokalnej 'x' zwrócone [domyślnie włączone]'. Może to zależeć od używanego kompilatora i/lub używanych przełączników kompilatora. –

+2

o to właśnie są ostrzeżenia, czas potraktować wszystkie ostrzeżenia jako błąd. – yngccc

+0

Uwaga: możesz powrócić przez stałe odniesienie i będzie dobrze – dchhetri

Odpowiedz

19

Większość kompilatorów wyświetli ostrzeżenie, gdy to zrobisz. Powinieneś zawsze włączać ostrzeżenia z opcją taką jak GCC -Wall.

Jeśli chodzi o przyczynę, dla której błąd nie jest wymagany przez standard, dzieje się tak, ponieważ funkcja z kontrolą przepływu utrudni określenie, czy zwracana wartość odnosi się do lokalnej, czy nie. (A niezdefiniowane zachowanie występuje tylko wtedy, gdy zwracana wartość jest używana przez wywołującego.)

+0

możesz podać przykład takiej sytuacji "trudnej do określenia", bez arytmetyki/kreacji wskaźnika? – Elazar

+8

@Elazar Sure, 'return fn (local_var);' Funkcja może zwrócić odwołanie do swojego argumentu, który jest zmienną lokalną. Lub 't & ref = flag? local: global; 'i later' return ref;'. Następnie kompilator musi udowodnić, że funkcja zwraca (w przeciwieństwie do wyjścia przez wyjątek) tylko wtedy, gdy "flaga" to "fałsz". – Potatoswatter

+0

Myślę, że kompilator powinien emitować ostrzeżenie dla 'return ref' wskazujące na wyrażenie warunkowe. To jest analiza "może". 'return fn (local)' to inna historia, zgadzam się. – Elazar