2010-10-27 2 views

risposta

18
#include <cstdlib> 
... 
exit(exit_code); 
+4

L'utilizzo dell'uscita non è piacevole. Rompe tutti quegli oggetti RAII che abbiamo speso tempo costruendo correttamente. È molto più bello tornare al main. Se invece il programma è corrotto, dovresti davvero chiamare std :: terminate() –

+0

@Martin, 'std :: terminate()' chiama semplicemente 'abort()' di default e 'abort()' termina il programma senza qualsiasi distruttore viene chiamato. –

+2

@ Whisty: Sì std :: terminate() è fondamentalmente la versione C++ di abort() (la differenza è che si può fare un over-ride e quindi fare una piccola quantità di clean up (I enfasi ** TINY **)). È una chiamata di ultima istanza (come abort()). Ma nel punto in cui i dati sono stati corrotti, non ha molto senso svincolare lo stack. Dati corrotti significa che non ci si può fidare di nulla (nemmeno lo stack si srotola). std :: terminate() è ciò che chiami quando non vuoi che lo stack si srotoli (perché non puoi fidarti di esso) e vuoi un core dump per il dubuging. –

3

Sì! exit(). È in <cstdlib>.

+3

Bene, 'std :: exit' really :) – ephemient

+0

Downvote per mancata dichiarazione di non responsabilità su come questo circonda il mondo felice di RAII. –

+0

Stai davvero rispondendo a eventi in downvote entro 2 secondi? Perché stavo ancora affermando la ragione mentre piangi già "Downvoter: Why?". /OK. Hai cancellato di nuovo il tuo pianto, invalidando parte del tempo che ho trascorso/perso. –

-4

uscita (0); // al termine della funzione principale prima di chiudere le parentesi graffe

+1

Perché? Il ritorno da 'main()' ha lo stesso effetto di chiamare 'exit()', con l'ulteriore vantaggio che qualsiasi variabile locale in 'main()' viene distrutta. –

25

Mentre è possibile chiamata exit() (e potrebbe essere necessario farlo se la vostra applicazione rileva qualche errore fatale), il modo più pulito per uscire da un programma è quello di tornare da main():

int main() 
{ 
    // do whatever your program does 

} // function returns and exits program 

Quando si chiama exit(), oggetti con durata memorizzazione automatica (variabili locali) non vengono distrutti prima che il programma termina, così non si ottiene una corretta pulizia. Questi oggetti potrebbero dover ripulire tutte le risorse che possiedono, persistere eventuali modifiche dello stato in sospeso, terminare eventuali thread in esecuzione o eseguire altre azioni affinché il programma possa terminare in modo pulito.

+7

E se è necessario uscire dal profondo del programma, un blocco try/catch in 'main' potrebbe essere preferibile a' exit() '. Questo è in realtà un aggravio di C. –

+0

Ricorda che è l'implementazione definita meteo che lo stack viene svolto se un'eccezione sfugge al main senza essere catturato. Quindi è più sicuro catturare tutte le eccezioni nel main poi rethrow. Dico rethrow visto che alcuni SO (Windows) cattureranno un'eccezione non catturata e faranno cose carine allo sviluppatore (non sono sicuro che questo si applichi solo al debug). –

+0

@Mark Ransom: [Non sono sicuro di aver capito correttamente] Immagino che quello di cui ho veramente bisogno, quando uso un blocco try-catch per il controllo del flusso, sia per il refactoring. –

0

In main(), v'è anche:

return 0; 
+2

Just 'return 0;'? Quindi, questo uscirebbe dal programma se avessi chiamato 'f()'? 'int f() {return 0; } ' –

+1

No - return 0 solo da main. exit() funziona da qualsiasi posizione – pm100

2

se ci si trova nella principale si può fare:

return 0; 

o

exit(exit_code); 

Il codice di uscita dipende la semantica del tuo codice. 1 è l'errore 0 e un'uscita normale.

In qualche altra funzione del vostro programma:

exit(exit_code) 

sarà uscire dal programma.

6

Ci sono diversi modi per far terminare il programma. Quale è appropriato dipende dal motivo per cui vuoi che il tuo programma termini. La maggior parte delle volte dovrebbe essere eseguendo una dichiarazione di ritorno nella funzione principale. Come nel seguito.

int main() 
{ 
    f(); 
    return 0; 
} 

Come altri hanno identificato questo permette tutte le variabili di stack ad essere adeguatamente distrutti in modo da ripulire correttamente. Questo è molto importante.

Se è stato rilevato un errore da qualche parte nel codice e è necessario uscire, è necessario generare un'eccezione per tornare alla funzione principale. Come nel seguito.

struct stop_now_t { }; 
void f() 
{ 
     // ... 
     if (some_condition()) 
      throw stop_now_t(); 
     // ... 
} 

int main() 
{ 
    try { 
      f(); 
    } catch (stop_now_t& stop) { 
      return 1; 
    } 
    return 0; 
} 

Questo fa sì che lo stack venga svolto e tutte le variabili dello stack vengano distrutte. Ancora molto importante. Si noti che è opportuno indicare un errore con un valore di ritorno diverso da zero.

Se nel caso improbabile che il programma rileva una condizione che indica che non è più sicuro di eseguire qualsiasi più istruzioni allora si dovrebbe usare std :: abort(). Questo porterà il tuo programma ad un arresto improvviso senza ulteriori elaborazioni. std :: exit() è simile, ma può chiamare atexit gestori che potrebbe essere male se il vostro programma è sufficientemente BORKED.

+0

Nota: 'std :: abort()' deve essere utilizzato per la chiusura immediata. 'std :: terminate()' dovrebbe essere usato solo dalle strutture di gestione delle eccezioni C++ quando la gestione delle eccezioni fallisce; non dovresti chiamarlo direttamente –

+0

A mio parere, un tipo di eccezione 'stop_now_t' è un abuso del sistema di eccezione. Il suo uso indicherebbe che state usando le eccezioni per il normale flusso di controllo (che di solito è cattivo). Una funzione non dovrebbe lanciare un'eccezione sapendo che verrà catturata solo in 'main()'; dovrebbe generare un'eccezione supponendo che possa essere catturata da qualsiasi chiamante in grado di gestire l'eccezione. –

+0

James, mi hai preso su std :: terminate(). Sì, std :: abort è una scelta migliore. Se un'eccezione come stop_now_t è appropriata dipende da come hai strutturato il tuo algoritmo. Concesso in un esempio così semplice, potrebbe essere un cattivo modo per farlo. Ma stavo solo cercando di illustrare come potrebbero essere usate le eccezioni. –

3

Consentire al flusso di esecuzione di lasciare main per returning a value or allowing execution to reach the end of the function è il modo in cui un programma deve terminare se non in circostanze irrecuperabili. Restituire un valore è facoltativo in C++, ma in genere preferisco restituire EXIT_SUCCESS trovato in cstdlib (un valore specifico della piattaforma che indica che il programma è stato eseguito correttamente).

#include <cstdlib> 

int main(int argc, char *argv[]) { 
    ... 
    return EXIT_SUCCESS; 
} 

Se, tuttavia, il programma raggiunge uno stato irreversibile, dovrebbe generare un'eccezione. È importante rendersi conto delle implicazioni di farlo, comunque. Non ci sono best practice largamente accettate per decidere cosa dovrebbe o non dovrebbe essere un'eccezione, ma ci sono alcune regole generali che devi conoscere.

Ad esempio, lanciare un'eccezione da un distruttore è quasi sempre una pessima idea perché l'oggetto distrutto potrebbe essere stato distrutto perché era già stata generata un'eccezione. Se viene lanciata una seconda eccezione, viene chiamato terminate e il programma si arresta senza che sia stata eseguita alcuna ulteriore pulizia. È possibile possibile utilizzare uncaught_exception per determinare se è sicuro, ma in genere è meglio non consentire mai eccezioni di lasciare un distruttore.

Mentre è generalmente sempre possibile per le funzioni che chiami, ma non ha scritto per lanciare eccezioni (per esempio, new getteranno std::bad_alloc se non può allocare memoria sufficiente), è spesso difficile per i programmatori principianti per tenere traccia di o anche sapere tutte le regole speciali che circondano le eccezioni in C++. Per questo motivo, consiglio di utilizzarli solo in situazioni in cui non esiste un modo ragionevole per il tuo programma di continuare l'esecuzione.

#include <stdexcept> 
#include <cstdlib> 
#include <iostream> 

int foo(int i) { 
    if (i != 5) { 
    throw std::runtime_error("foo: i is not 5!"); 
    } 
    return i * 2; 
} 

int main(int argc, char *argv[]) { 
    try { 
    foo(3); 
    } 
    catch (const std::exception &e) { 
    std::cout << e.what() << std::endl; 
    return EXIT_FAILURE; 
    } 
    return EXIT_SUCCESS; 
} 

exit è una rapina sulla C e può comportare oggetti con memorizzazione automatica di non essere ripulito correttamente. abort e terminate effettivamente causa il suicidio del programma e sicuramente non pulirà le risorse.

Qualunque cosa tu faccia, non utilizzare le eccezioni, exit o abort/terminate come una stampella per aggirare la scrittura di un programma ben strutturato. Salvali per situazioni eccezionali.

0
#include <cstdlib> 
... 
/*wherever you want it to end, e.g. in an if-statement:*/ 
if (T == 0) 
{ 
exit(0); 
} 
-3

abbastanza semplice ..

exit (0); } // fine della funzione

Assicurarsi che vi sia uno spazio su entrambi i lati dello 0. Senza spazi, il programma non si fermerà.

+3

Gli spazi non hanno nulla a che fare con questo. –

-1
else if(Decision >= 3) 
    { 
exit(0); 
    } 
+1

Come indicato nei commenti su altre risposte, usare 'exit' è in realtà un modo piuttosto brutto di terminare il programma - il modo peggiore che c'è (tra molti possibili), direi. –