Partager via


Fonction main et arguments de ligne de commande

Tous les programmes C++ doivent avoir une fonction main. Si vous essayez de compiler un programme C++ sans fonction main, le compilateur génère une erreur. (Les bibliothèques de liens dynamiques et les bibliothèques static n’ont pas de fonction main.) La fonction main est l’endroit où votre code source commence l’exécution, mais avant qu’un programme entre dans la fonction main, tous les membres de classe static sans initialiseurs explicites sont définis sur zéro. Dans Microsoft C++, les objets globaux static sont également initialisés avant l’entrée dans main. Plusieurs restrictions s’appliquent à la fonction main, qui ne s’appliquent à aucune autre fonction C++. La fonction main :

  • Ne peut pas être surchargée (consulter Surcharge de fonction).
  • Ne peut pas être déclaré en tant que inline.
  • Ne peut pas être déclaré en tant que static.
  • Son adresse ne peut pas être prise.
  • Ne peut pas être appelée à partir de votre programme.

Signature de la fonction main

La fonction main n’a pas de déclaration, car elle est intégrée au langage. Si elle en avait, la syntaxe de déclaration pour main ressemblerait à ceci :

int main();
int main(int argc, char *argv[]);

Si aucune valeur de retour n’est spécifiée dans main, le compilateur fournit une valeur de retour de zéro.

Arguments de ligne de commande standard

Les arguments pour main permettent d'analyser facilement les arguments sur la ligne de commande. Les types pour argc et argv sont définis par le langage. Les noms argc et argv sont traditionnellement utilisés, mais vous pouvez les nommer comme vous le souhaitez.

Les définitions d’argument sont les suivantes :

argc
Entier qui contient le nombre d’arguments qui se suivent dans argv. Le paramètre argc est toujours supérieur ou égal à 1.

argv
Tableau de chaînes terminées par le caractère NULL qui représentent les arguments de ligne de commande entrés par l’utilisateur du programme. Par convention, argv[0] est la commande avec laquelle le programme est appelé. argv[1] est le premier argument de ligne de commande. Le dernier argument de ligne de commande est argv[argc - 1] et argv[argc] a toujours NULL pour valeur.

Pour en savoir plus sur la suppression du traitement en ligne de commande, veuillez consulter Personnalisation du traitement de ligne de commande C++.

Remarque

Par convention, argv[0] est le nom du fichier du programme. Toutefois, sous Windows, il est possible de générer un processus avec CreateProcess. Si vous utilisez à la fois le premier et le deuxième argument (lpApplicationName et lpCommandLine), il se peut que le nom exécutable ne soit pas argv[0]. Vous pouvez utiliser GetModuleFileName pour récupérer le nom exécutable et son chemin d’accès complet.

Extensions spécifiques à Microsoft

Les sections suivantes décrivent le comportement spécifique à Microsoft.

Fonction wmain et macro _tmain

Si vous concevez votre code source pour utiliser des caractères larges Unicode, vous pouvez utiliser le point d’entrée spécifique à Microsoft wmain, qui est la version en caractères larges de main. Voici la syntaxe de déclaration effective pour wmain :

int wmain();
int wmain(int argc, wchar_t *argv[]);

Vous pouvez également utiliser la macro _tmain spécifique à Microsoft, qui est une macro de préprocesseur définie dans tchar.h. _tmain se résout dans main sauf si _UNICODE est défini. Dans ce cas, _tmain est résolu à wmain. La macro _tmain et d’autres macros qui commencent par _t sont utiles pour un code qui doit être compilé en versions distinctes pour les ensembles de caractères étroits et larges. Pour plus d’informations, consultez Utilisation de mappages de texte générique.

void renvoyé à partir de main

En tant qu’extension Microsoft, les fonctions main et wmain peuvent être déclarées comme renvoyant void (aucune valeur de retour). Cette extension est également disponible dans d’autres compilateurs, mais son utilisation n’est pas recommandée. Elle est disponible pour la symétrie lorsque main ne renvoie pas de valeur.

Si vous déclarez main ou wmain comme renvoyant void, vous ne pouvez pas renvoyer de code exit au processus parent ou au système d’exploitation en utilisant une instruction return. Pour renvoyer un code exit lorsque main ou wmain est déclaré en tant que void, vous devez utiliser la fonction exit.

Argument de ligne de commande envp

Les signatures main et wmain autorisent une extension spécifique à Microsoft facultative pour l’accès aux variables d’environnement. Cette extension est également courante dans d’autres compilateurs pour les systèmes Windows et UNIX. Le nom envp est traditionnel, mais vous pouvez nommer le paramètre d’environnement comme vous le souhaitez. Voici les déclarations effectives des listes d’arguments qui incluent le paramètre d’environnement :

int main(int argc, char* argv[], char* envp[]);
int wmain(int argc, wchar_t* argv[], wchar_t* envp[]);

envp
Le paramètre facultatif envp est un tableau de chaînes représentant les variables définies dans l'environnement de l'utilisateur. Ce tableau se termine par une entrée NULL. Il peut être déclaré comme tableau de pointeurs en type char (char *envp[]) ou comme pointeur vers des pointeurs en type char (char **envp). Si votre programme utilise wmain au lieu de main, utilisez le type de données wchar_t au lieu de char.

Le bloc d’environnement passé à main et wmain est une copie « figée » de l’environnement actuel. Si vous modifiez ultérieurement l’environnement via un appel à putenv ou _wputenv, l’environnement actuel (tel que renvoyé par getenv ou _wgetenv et la variable _environ ou _wenviron) change, mais pas le bloc vers lequel envp pointe. Pour en savoir plus sur la suppression du traitement d’environnement, veuillez consulter Personnalisation du traitement de ligne de commande C++. L’argument envp est compatible avec la norme C89, mais pas avec les normes C++.

Exemples d’arguments pour main

L’exemple suivant montre comment utiliser les arguments argc, argv et envp pour main :

// argument_definitions.cpp
// compile with: /EHsc
#include <iostream>
#include <string.h>

using namespace std;
int main( int argc, char *argv[], char *envp[] )
{
    bool numberLines = false;    // Default is no line numbers.

    // If /n is passed to the .exe, display numbered listing
    // of environment variables.
    if ( (argc == 2) && _stricmp( argv[1], "/n" ) == 0 )
         numberLines = true;

    // Walk through list of strings until a NULL is encountered.
    for ( int i = 0; envp[i] != NULL; ++i )
    {
        if ( numberLines )
            cout << i << ": "; // Prefix with numbers if /n specified
        cout << envp[i] << "\n";
    }
}

Analyse des arguments de ligne de commande C++

Les règles d’analyse de ligne de commande utilisées par le code Microsoft C/C++ sont spécifiques à Microsoft. Le code de démarrage du runtime utilise ces règles lors de l’interprétation des arguments spécifiés dans la ligne de commande du système d’exploitation :

  • Les arguments sont délimités par un espace blanc, qui peut être un espace ou une tabulation.

  • Le premier argument (argv[0]) est traité de manière spéciale. Il représente le nom du programme. Comme il doit s’agir d’un nom de chemin d’accès valide, les parties entourées de guillemets doubles (") sont autorisées. Les guillemets doubles ne sont pas inclus dans la sortie argv[0]. Les parties entourées de guillemets doubles empêchent l’interprétation d’une espace ou d’une tabulation comme la fin de l’argument. Les règles suivantes répertoriées dans cette liste ne s’appliquent pas.

  • Une chaîne entourée de guillemets doubles est interprétée comme un seul argument, qui peut contenir des caractères d’espacement. Une chaîne entre guillemets peut être incorporée dans un argument. L’accent circonflexe (^) n’est pas reconnu comme un caractère d’échappement ou un délimiteur. Dans une chaîne entre guillemets, une paire de guillemets doubles est interprétée comme un seul guillemet double échappé. Si la ligne de commande se termine avant qu’un guillemet double fermant soit trouvé, tous les caractères lus jusque là constituent le dernier argument.

  • Un guillemet double précédé d’une barre oblique inverse (\") est interprété comme un guillemet double littéral (").

  • Les barres obliques inverses sont interprétées littéralement, sauf si elles précèdent immédiatement un guillemet double.

  • Si un nombre pair de barres obliques inverses est suivi d’un guillemet double, une barre oblique inverse (\) est placée dans le tableau argv pour chaque paire de barres obliques inverses (\\) et le guillemet double (") est interprété comme un délimiteur de chaîne.

  • Si un nombre impair de barres obliques inverses est suivi d’un guillemet double, une barre oblique inverse (\) est placée dans le tableau argv pour chaque paire de barres obliques inverses (\\). Le guillemet double est interprété comme une séquence d’échappement par la barre oblique inverse restante, ce qui entraîne le placement d’un guillemet double littéral (") dans argv.

Exemple d’analyse d’argument de ligne de commande

Le programme suivant montre comment les arguments de ligne de commande sont passés :

// command_line_arguments.cpp
// compile with: /EHsc
#include <iostream>

using namespace std;
int main( int argc,      // Number of strings in array argv
          char *argv[],   // Array of command-line argument strings
          char *envp[] )  // Array of environment variable strings
{
    int count;

    // Display each command-line argument.
    cout << "\nCommand-line arguments:\n";
    for( count = 0; count < argc; count++ )
         cout << "  argv[" << count << "]   "
                << argv[count] << "\n";
}

Résultats de l’analyse des lignes de commande

Le tableau suivant présente un exemple d’entrée et de sortie attendue, illustrant les règles de la liste précédente.

Entrée de ligne de commande argv[1] argv[2] argv[3]
"abc" d e abc d e
a\\b d"e f"g h a\\b de fg h
a\\\"b c d a\"b c d
a\\\\"b c" d e a\\b c d e
a"b"" c d ab" c d

Développement des caractères génériques

Le compilateur Microsoft vous permet en option d’utiliser des caractères wildcard, le point d’interrogation (?) et l’astérisque (*), pour spécifier des arguments de nom de fichier et de chemin dans la ligne de commande.

Les arguments de ligne de commande sont gérés par une routine interne dans le code de démarrage du runtime, qui par défaut ne développe pas les caractères génériques dans des chaînes distinctes du tableau de chaînes argv. Vous pouvez activer le développement des caractères générique en incluant le fichier setargv.obj (fichier wsetargv.obj pour wmain) dans les options de votre compilateur /link ou votre ligne de commande LINK.

Pour plus d’informations sur les options de l’éditeur de liens de démarrage du runtime, consultez Options de lien.

Personnalisation du traitement de ligne de commande C++

Si votre programme ne prend pas d’arguments de ligne de commande, vous pouvez supprimer la routine de traitement de ligne de commande pour économiser une petite quantité d’espace. Pour supprimer son utilisation, incluez le fichier noarg.obj (pour main et wmain) dans vos options de compilateur /link ou votre ligne de commande LINK.

De même, si vous n’accédez jamais à la table d’environnement par le biais de l’argument envp, vous pouvez supprimer la routine de traitement de l’environnement interne. Pour supprimer son utilisation, incluez le fichier noenv.obj (pour main et wmain) dans vos options de compilateur /link ou votre ligne de commande LINK.

Votre programme peut effectuer des appels à la famille de routines spawn ou exec dans la bibliothèque Runtime C. Si c’est le cas, vous ne devez pas supprimer la routine de traitement de l’environnement, car elle est utilisée pour transmettre un environnement du processus parent au processus enfant.

Voir aussi

Concepts de base