2013-02-04 6 views
11

C'è l'avviso C4172 Visual C++ per i casi in cui una funzione restituisce un indirizzo locale o temporaneo o un riferimento a una variabile locale.Esistono scenari in cui l'avviso C4172 Visual C++ non deve essere considerato un errore?

Qualcosa di simile a questo:

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

Ora sembra che sia una buona idea usare #pragma warning per rendere Visual C++ trattare C4172 come errore e rompere la compilazione.

Esistono scenari sane in cui C4172 non è effettivamente un errore?

+0

Quindi, si vuole sapere se va bene a trattarlo in modo permanente come un errore - che significa: perché è stato definito come un avvertimento per iniziare? Grande domanda. –

+3

Probabilmente no, e il compilatore ha ragione a fornirlo come errore diagnostico e non come compilazione perché è un comportamento indefinito per restituire il riferimento a un errore di sintassi locale e non a un linguaggio. Perché non è definito come errore di sintassi della lingua? Perché non è un errore di sintassi. –

+0

@jim mcnamara: Sì, hai ragione. – sharptooth

risposta

8

non sono sicuro perché qualcuno dovrebbe mai voler fare questo:

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

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

Ma in generale, si dovrebbe trattare l'avviso come un errore.

+0

Un esempio un po 'più sano: scoprire quanto è grande un frame dello stack minimo (= dimensione dell'indirizzo di ritorno?) –

+4

Se comprendo lo standard C, confrontando i puntatori con>, <, > = e <= risultati comportamento indefinito se quei puntatori non puntano nello stesso oggetto aggregato (struct/union) o agli elementi della stessa matrice (incluso l'elemento inesistente dopo l'ultimo). Penso che il C++ sia lo stesso qui. –

+1

@AlexeyFrunze: vero, * ma * 'std :: less ' è definito per i puntatori, anche se non puntano a elementi della stessa matrice. –

4

È un avviso di livello 1, molto difficile da ignorare. Ma il compilatore segue gli standard linguistici qui, invocando UB non è proibito. Ed è un bug molto comune che troppo spesso arriva a una buona fine. La posizione di pila puntata rimane stabile finché non si effettuano chiamate di funzione.

Il modo migliore per risolvere questo problema consiste nel trasformare gli avvisi in errori. Compilare con/WX, l'impostazione "Tratta avvertimenti come errori" nell'IDE. Se poi vuoi intenzionalmente sopprimere un avvertimento, l'avvertimento #pragma chiarisce a tutti che sta succedendo qualcosa di sospetto a cui si è pensato e non un incidente.

0

codice non utilizzato

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 } 
} 
Problemi correlati