115 votes

"Argv [0] = nom-exécutable" est-il un standard accepté ou juste une convention commune?

Lorsque vous transmettez l'argument à main() dans une application C ou C ++, argv[0] sera-t-il toujours le nom de l'exécutable? Ou est-ce juste une convention commune et il n'est pas garanti que ce soit vrai 100% du temps?

130voto

paxdiablo Points 341644

Conjecture (même instruites conjecture) est amusant, mais vous avez vraiment besoin d'aller à l'documents de normes pour être sûr. Par exemple, le c1x n1425 projet d'états:

Si la valeur de argc est supérieure à zéro, la chaîne pointée par argv[0] représente le nom du programme; argv[0][0] est le caractère null si le nom du programme n'est pas disponible à partir de l'hôte de l'environnement.

Donc non, c'est seulement le nom du programme si le nom est disponible. Et il "représente" le nom du programme, pas nécessairement est le nom du programme. La section avant que les états:

Si la valeur de argc est supérieure à zéro, les membres du tableau argv[0] par argv[argc-1] inclusive doit contenir des pointeurs vers des chaînes, qui sont donnés en œuvre les valeurs définies par l'hôte de l'environnement avant le démarrage du programme.

C'est le même qu'en C99, la norme précédente, et signifie que même les valeurs ne sont pas dictés par la norme - c'est à la mise en œuvre entièrement.

Cela signifie que le nom du programme peut être vide si l'hôte de l'environnement de ne pas les fournir, et rien d'autre, si l'hôte de l'environnement ne fournir, à la condition que "rien d'autre" représente en quelque sorte le nom du programme. Dans mon plus sadique moments, je considère la traduction en Swahili, en cours d'exécution à travers un mécanisme de chiffrement par substitution stocker ensuite dans le sens inverse de l'ordre des octets :-).

Cependant, la mise en œuvre définies n' ont une signification particulière dans les normes ISO - la mise en œuvre doit documenter la façon dont il fonctionne. Donc, même UNIX, ce qui peut mettre tout ce qu'il aime en argv[0] avec l' exec famille d'appels, de a à (et) du document.

53voto

Richard Pennington Points 12912

En vertu de l' *nix type de systèmes avec exec*() des appels, argv[0] seront celles que l'appelant met dans la argv0 spot dans l' exec*() appel.

Le shell utilise la convention que c'est le nom du programme, et la plupart des autres programmes de la même convention, de sorte argv[0] habituellement le nom du programme.

Mais un voyou Unix programme peut appeler exec() et faire argv[0] tout ce qu'il aime, alors peu importe ce que la norme dit, vous ne pouvez pas compter sur ce 100% du temps.

7voto

Gregory Pakosz Points 35546

ISO-IEC 9899 états:

5.1.2.2.1 démarrage du Programme

Si la valeur de argc , est supérieure à zéro, la chaîne pointée par argv[0] représente le programme; argv[0][0] doit être le caractère null si le nom du programme n'est pas disponible à partir de l'hôte de l'environnement. Si la valeur de argc est supérieur à un, les chaînes de caractères pointée par argv[1] par argv[argc-1] représentent les paramètres du programme.

J'ai aussi utilisé:

#if defined(_WIN32)
  static size_t getExecutablePathName(char* pathName, size_t pathNameCapacity)
  {
    return GetModuleFileNameA(NULL, pathName, (DWORD)pathNameCapacity);
  }
#elif defined(__linux__) /* elif of: #if defined(_WIN32) */
  #include <unistd.h>
  static size_t getExecutablePathName(char* pathName, size_t pathNameCapacity)
  {
    size_t pathNameSize = readlink("/proc/self/exe", pathName, pathNameCapacity - 1);
    pathName[pathNameSize] = '\0';
    return pathNameSize;
  }
#elif defined(__APPLE__) /* elif of: #elif defined(__linux__) */
  #include <mach-o/dyld.h>
  static size_t getExecutablePathName(char* pathName, size_t pathNameCapacity)
  {
    uint32_t pathNameSize = 0;

    _NSGetExecutablePath(NULL, &pathNameSize);

    if (pathNameSize > pathNameCapacity)
      pathNameSize = pathNameCapacity;

    if (!_NSGetExecutablePath(pathName, &pathNameSize))
    {
      char real[PATH_MAX];

      if (realpath(pathName, real) != NULL)
      {
        pathNameSize = strlen(real);
        strncpy(pathName, real, pathNameSize);
      }

      return pathNameSize;
    }

    return 0;
  }
#else /* else of: #elif defined(__APPLE__) */
  #error provide your own implementation
#endif /* end of: #if defined(_WIN32) */

Et puis vous avez juste à analyser la chaîne à extraire le nom de l'exécutable à partir du chemin d'accès.

3voto

ChrisF Points 74295

Cette page membres:

L'élément argv[0] contient normalement le nom du programme, mais cela ne devrait pas être invoqué - de toute façon, il est inhabituel pour un programme à ne pas connaître son propre nom!

Cependant, d'autres pages semblent sauvegarder le fait qu'il est toujours le nom de l'exécutable. Ce l'un des états:

Vous remarquerez que argv[0] est le chemin d'accès et le nom du programme lui-même. Cela permet au programme pour découvrir des informations sur lui-même. Il ajoute également un plus à l'ensemble des arguments du programme, ainsi, une commune erreur lors de la récupération des arguments de ligne de commande, c'est de prendre argv[0] lorsque vous voulez argv[1].

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X