2015-07-26 2 views
5

Ho un programma:eccezioni- comportamenti scorretti in VC++ 2015 CTP ultimo

#include<iostream> 
using namespace std; 

class Test 
{ 
public: 
    void func() 
    { 
     cout << "Inside func" << endl; 
     throw; 
    } 
}; 

int myfunc() 
{ 
    Test T; 
    T.func(); 
    return 1; 
} 

int main() 
{ 
    myfunc(); 
    cout << "Main func" << endl;//should not print 
    getchar(); 
} 

La mia aspettativa era questo programma sarebbe sospendere dal main, ma su VC++ 2015 il maincout si stava stampato. Che era contro la mia comprensione, quindi l'ho compilato con gcc e funziona bene lì.

Si tratta di un bug in VC++ 2015 o il comportamento della terminazione del programma come questo è il comportamento non specificato/UB? Dovrebbe mai eseguire cout << "Main func" << endl;?

IDE: VS2015 CTP ultima anteprima (per 30 giorni)

bandiere: /GS /analyze- /W3 /Zc:wchar_t /ZI /Gm /Od /sdl /Fd"Debug\vc140.pdb" /fp:precise /D "_MBCS" /errorReport:prompt /WX- /Zc:forScope /RTC1 /Gd /Oy- /MDd /Fa"Debug\" /EHsc /nologo /Fo"Debug\" /Fp"Debug\exception.pch"

+0

Potrebbe fornire i flag del compilatore utilizzati per la compilazione, per favore? – namezero

+0

Cosa succede se si utilizza la versione finale di VS2015? CTP è piuttosto vecchio, tra RTM e CTP c'era anche un RC. –

+0

@namezero: dove lo trovo? Comunque non ho ancora cambiato le impostazioni di default. – InQusitive

risposta

5

throw senza un argomento, quando viene chiamato in un contesto improprio, devono chiamare terminate.

Secondo la norma:

A rimessa espressione senza operando genera nuovamente l'eccezione attualmente gestita

....

Se è attualmente gestita non fa eccezione, l'esecuzione a espressione-lancio senza chiamate di operandi std::terminate()

Quindi il comportamento dipende dal std::terminate_handler attualmente installato, ma in ogni caso l'esecuzione dovrebbe essere terminata.

Richiesto comportamento: Un terminate_handler deve interrompere l'esecuzione del programma senza tornare al chiamante.

Comportamento predefinito: l'impostazione predefinita dell'implementazione terminate_handler chiama abort. L'implementazione predefinita chiama std::abort.

+0

quindi è un bug? – InQusitive

+0

Sembra un po 'strano. Hai un 'terminate_handler' personalizzato? – AlexD

+0

No, ho solo questo codice, nessun'altra modifica. – InQusitive

1

Immagino che tu stia eseguendo il tuo programma di test in ambiente di debug VS. Prova a compilare il tuo programma in release build ed eseguilo facendo clic sul file eseguibile. La finestra di errore dell'eccezione verrà visualizzata e la "Funzione principale" non verrà stampata. In effetti, il comportamento nel debugger VS è una funzionalità piuttosto che un bug.

Microsoft afferma che here:

In Visual Studio, quando le eccezioni sono gettati o finiscono per non gestita, il debugger può aiutare il debug questi rompendo proprio come si rompe quando un punto di interruzione viene colpito.

A questo punto lo sviluppatore può risolvere ciò che non va o continuare l'esecuzione che porterà al comportamento del manifesto, ad esempiola stampa del main func nella sua domanda.

+0

Anche una compilazione di debug dovrebbe essere sufficiente (argomento del comportamento osservabile). Con un debugger collegato, un punto di interruzione viene solitamente attivato in abort(). – namezero

+0

@namezero: quando passo alla modalità di rilascio, fornisce un comportamento previsto. – InQusitive

+0

Ho fatto il test con il modo in cui ho postato prima di pubblicare. Il debugger si comporta diversamente come eseguibile del rilascio. Il debugger consente la stampa del "Main func", ma l'eseguibile del rilascio no. – simon