2014-06-08 17 views
5

Co to jest wartość logiczna, która jest zwracana, gdy wywołanie funkcji fucntion jest wykonywane na obiekcie zerowym w C++?Wartość logiczna zwracana w wywołaniu funkcji do obiektu zerowego

ClassDummy* dummy = NULL; 
if (!dummy->dummy_function(1,2,3)) { 
    // Do Something 
} 

Czy ten błąd nie powinien zwrócony zgodnie ze standardami C++ 11?

+0

I odpowiedzieć na całą swoją przyszłość "nie powinienem mówić w C++, że robię coś złego" z wyprzedzeniem: nie. C++ optymalizuje w dużym stopniu przypadek, w którym działa twój program, kosztem mówienia prawie nic o przypadku, w którym masz błąd. – user2357112

Odpowiedz

2

Wywołanie metody za pomocą wskaźnika pustego ma niezdefiniowane zachowanie. Kod jest nieprawidłowy, ale kompilator nie musi Cię o tym informować.

Standard C++ definiuje wiele przypadków, w których, mimo że kod jest nieprawidłowy, kompilator nie musi podawać "diagnostyki". W wielu przypadkach powodem jest fakt, że kompilator ma trudności z ustaleniem, czy kod jest ważny. W twoim konkretnym kodzie jest to dość łatwe, a niektóre kompilatory mogą w rzeczywistości ostrzegać o tym, jeśli użyjesz odpowiedniego poziomu ostrzeżenia. Jednak nie byłoby zbyt trudno skonstruować bardziej skomplikowany przykład, w którym kompilator nie mógłby łatwo stwierdzić, czy wskaźnik był pusty, czy nie. Standaryzacja tego, jak skomplikowany musi być kod, zanim kompilator nie będzie wymagał diagnostyki, byłaby trudna i prawdopodobnie bezcelowa, dlatego każda decyzja musi zostać podjęta, aby podjąć taką decyzję.

4

W oryginalnym pytaniu dummy miał nieokreśloną wartość, może zero. Efekt po zmianie nie jest jednak zmieniony: zachowanie to undefined. Nie jest to błąd, który jest wymagany do wykrycia jakiegokolwiek narzędzia: jest to mandat programisty do wywoływania funkcji składowej tylko na poprawnych obiektach.

+0

Zmieniłem trochę pytanie. Czy wystąpiłby błąd, gdyby wskaźnik był wyraźnie oznaczony NULL? – ibp73

+4

nie. wciąż ten sam. ... i jeśli potrzebujesz wyjaśnienia znaczenia [niezdefiniowanej] (http://dspace.dial.pipex.com/town/green/gfd34/art/bloopers.html): kliknij link! –

+0

@ DietmarKühl, Wow, raczej mi się podoba. – chris

5

O ile nie został zadeklarowany dummy w zasięgu obszaru nazw, nie jest on inicjowany, a jego wartość jest nieokreślona, ​​tj. Może być, ale nie musi, być pusta. Wywołanie funkcji składowej na nullptr lub na wskaźniku wskazującym na niepoprawną pamięć to niezdefiniowane zachowanie.

Użytkownik może uzyskać get away with the correct result, jeśli wywoływana funkcja członkowska nie ma dostępu do żadnych innych elementów danych klasy; innymi słowy, jeśli nie wyłuskuje wskaźnika this. Jednak niezależnie od tego, czy uzyskasz oczekiwany wynik, czy nie, nadal jest to niezdefiniowane zachowanie.

Kompilatory nie są wymagane do wykrywania takich nieprawidłowych wywołań funkcji. Jeśli zrobisz coś oczywistego, np. Zainicjuj wskaźnik obiektu na nullptr, a następnie wywołaj na nim funkcję składową, możesz zobaczyć diagnostykę z kompilatora, ale nie jest to gwarantowane.

2

Próba dereferencji wskaźnika pustego w ten sposób spowoduje niezdefiniowane zachowanie.

(Zazwyczaj zrzutu lub dostępu do pamięci wyjątków w większości systemów.)

+2

I zwykle po cichu pojawia się do pracy, jeśli wywoływana jest nie-wirtualna funkcja członkowska, która nie ma dostępu do '* this'. – hvd

+0

@hvd W każdym razie, to jest złe. – songyuanyao

0

niewymagających-statyczne metody i dostępu niestatycznych zmienne powinno prowadzić do błędów.

Niektóre środowiska kompilujące i działające pozwalają na użycie zmiennych składowych static i funkcji składowych z wskaźnikiem NULL, ale to nadal jest niezdefiniowane zachowanie zgodnie ze standardem.

Zobacz C++ static const access through a NULL pointer i zaakceptowaną odpowiedź, aby uzyskać więcej informacji.

Powiązane problemy