Arrêt du programme C++
En C++, vous pouvez quitter un programme de ces manières :
- Appelez la fonction
exit
. - Appelez la fonction
abort
. - Exécutez une
return
instruction à partir demain
.
Fonction exit
La exit
fonction, déclarée dans <stdlib.h>, met fin à un programme C++. La valeur fournie en tant qu’argument à exit
retourner au système d’exploitation en tant que code de retour ou code de sortie du programme. Par convention, un code de retour égal à zéro signifie que le programme s'est terminé correctement. Vous pouvez utiliser les constantes EXIT_FAILURE
et EXIT_SUCCESS
, également définies dans <stdlib.h>, pour indiquer la réussite ou l’échec de votre programme.
Fonction abort
La abort
fonction, également déclarée dans le fichier <include standard stdlib.h>, met fin à un programme C++. La différence entre exit
et abort
c’est que exit
le traitement de terminaison du runtime C++ a lieu (les destructeurs d’objets globaux sont appelés). abort
termine immédiatement le programme. La abort
fonction contourne le processus de destruction normal pour les objets statiques globaux initialisés. Il ignore également tout traitement spécial qui a été spécifié avec la fonction atexit
.
Spécifique à Microsoft : pour des raisons de compatibilité Windows, l’implémentation Microsoft peut autoriser l’exécution du code de abort
terminaison DLL dans certaines circonstances. Pour plus d’informations, consultez abort
.
Fonction atexit
Utilisez la atexit
fonction pour spécifier les actions qui s’exécutent avant la fin du programme. Aucun objet statique global initialisé avant que l’appel ne atexit
soit détruit avant l’exécution de la fonction de traitement de sortie.
return
instruction dans main
L’instruction return
vous permet de spécifier une valeur de retour à partir de main
. Dans un premier temps, une return
instruction main
agit comme toute autre return
instruction. Toutes les variables automatiques sont détruites. Ensuite, main
appelle exit
avec la valeur de retour en tant que paramètre. Prenons l’exemple suivant :
// return_statement.cpp
#include <stdlib.h>
struct S
{
int value;
};
int main()
{
S s{ 3 };
exit( 3 );
// or
return 3;
}
Les exit
instructions de return
l’exemple précédent ont un comportement similaire. Les deux arrêtent le programme et retournent une valeur de 3 au système d’exploitation. La différence est que exit
ne détruit pas la variable s
automatique, tandis que l’instruction return
le fait.
Normalement, C++ requiert que les fonctions qui ont des types de retour autres que void
le retour d’une valeur. La main
fonction est une exception ; elle peut se terminer sans return
instruction. Dans ce cas, elle retourne une valeur spécifique à l’implémentation au processus d’appel. (Par défaut, MSVC retourne 0.)
Destruction de threads et d’objets statiques
Lorsque vous appelez exit
directement (ou lorsqu’il est appelé après une return
instruction de ), main
les objets thread associés au thread actuel sont détruits. Ensuite, les objets statiques sont détruits dans l’ordre inverse de leur initialisation (après les appels aux fonctions spécifiées à atexit
, le cas échéant). L'exemple suivant montre comment ce type d'initialisation et de nettoyage fonctionne.
Exemple
Dans l’exemple suivant, les objets sd1
statiques et sd2
sont créés et initialisés avant l’entrée main
. Une fois que ce programme se termine à l’aide de l’instruction, il est d’abord return
sd2
détruit, puis sd1
. Le destructeur de la classe ShowData
ferme les fichiers associés à ces objets statiques.
// using_exit_or_return1.cpp
#include <stdio.h>
class ShowData {
public:
// Constructor opens a file.
ShowData( const char *szDev ) {
errno_t err;
err = fopen_s(&OutputDev, szDev, "w" );
}
// Destructor closes the file.
~ShowData() { fclose( OutputDev ); }
// Disp function shows a string on the output device.
void Disp( char *szData ) {
fputs( szData, OutputDev );
}
private:
FILE *OutputDev;
};
// Define a static object of type ShowData. The output device
// selected is "CON" -- the standard output device.
ShowData sd1 = "CON";
// Define another static object of type ShowData. The output
// is directed to a file called "HELLO.DAT"
ShowData sd2 = "hello.dat";
int main() {
sd1.Disp( "hello to default device\n" );
sd2.Disp( "hello to file hello.dat\n" );
}
Une autre façon d’écrire ce code consiste à déclarer les ShowData
objets avec une étendue de bloc, ce qui les détruit implicitement lorsqu’ils sortent de l’étendue :
int main() {
ShowData sd1( "CON" ), sd2( "hello.dat" );
sd1.Disp( "hello to default device\n" );
sd2.Disp( "hello to file hello.dat\n" );
}