2013-02-04 13 views
11

Jest C4172 Ostrzeżenie Visual C++ dla przypadków, gdy funkcja zwraca adres lokalnego lub tymczasowego lub odniesienie do zmiennej lokalnej.Czy są jakieś scenariusze, w których ostrzeżenie C4172 Visual C++ nie powinno być uważane za błąd?

coś takiego:

int& fun() 
{ 
    int var; 
    return var; //C4172 
} 

Teraz wygląda na to, że jest to dobry pomysł, aby użyć #pragma warning aby Visual C++ leczenia C4172 jako błąd i złamać kompilację.

Czy są jakieś rozsądne scenariusze, w których C4172 w rzeczywistości nie jest błędem?

+0

Więc chcesz wiedzieć, czy to jest w porządku, aby traktować go trwale jako błąd - znaczenie: dlaczego została ona zdefiniowana jako ostrzeżenie na początek? Świetne pytanie. –

+3

Najprawdopodobniej nie, a kompilator ma rację, przedstawiając go jako błąd diagnostyczny, a nie jako kompilację, ponieważ nieokreślonym zachowaniem jest zwracanie odwołania do błędu składni lokalnej, a nie błędu składni języka. Dlaczego nie zdefiniowano go jako błąd składni języka? Ponieważ nie jest to błąd składniowy. –

+0

@jim mcnamara: Tak, masz rację. – sharptooth

Odpowiedz

8

Nie jestem pewien, dlaczego ktoś miałby kiedykolwiek chcesz to zrobić:

int * stackTester() 
{ 
    int dummy; 
    return &dummy; 
} 

bool stackGoesUp() 
{ 
    int dummy; 
    return stackTester() > &dummy; 
} 

Ale ogólnie rzecz biorąc, należy traktować jak ostrzeżenie błędu.

+0

Nieco bardziej przyzwoitym przykładzie: dowiedzieć się, jak duża jest minimalna ramka stosu (= rozmiar adresu zwrotnego?) –

+4

Jeśli rozumiem standard C, porównywanie wskaźników z>, <, > = i <= powoduje niezdefiniowane zachowanie jeśli te wskaźniki nie wskazują tego samego obiektu zbiorczego (struct/union) lub elementów tej samej tablicy (w tym nieistniejącego elementu po ostatnim). Myślę, że C++ jest tutaj taki sam. –

+1

@AlexeyFrunze: True, * ale * 'std :: less ' jest zdefiniowane dla wskaźników, nawet jeśli nie wskazują one na elementy tej samej tablicy. –

4

Jest to ostrzeżenie na poziomie 1, bardzo trudne do zignorowania. Ale kompilator przestrzega tutaj standardów językowych, nie jest zabronione odwoływanie się do UB. Jest to bardzo powszechny błąd, który zbyt często kończy się dobrze. Położenie wskazanego stosu pozostaje stabilne, o ile nie wykonujesz żadnych wywołań funkcji.

Najlepszym sposobem radzenia sobie z tym jest zamienianie ostrzeżeń w błędy. Skompiluj z/WX, ustawienie "Traktuj ostrzeżenia jako błędy" w IDE. Jeśli następnie umyślnie chcesz wyłączyć ostrzeżenie, to #pragma ostrzeżenie uświadomi wszystkim, że dzieje się coś podejrzanego, a nie przypadek.

0

nieużywany kod

class base 
{ 
    virtual blah& makeBlah() 
} 

class red : public base 
{ 
    blah& makeBlah() { return blah(); } // there are no red blahs, never called 
} 

class blue : public base 
{ 
    blah& makeBlah() { actual code to make a blah } 
} 
Powiązane problemy