Frage

In der C / Unix-Umgebung ich arbeite, sehe ich einige Entwickler mit __progname statt argv[0] für die Nutzung Nachrichten. Gibt es einen Vorteil zu diesem? Was ist der Unterschied zwischen __progname und argv[0]. Ist es tragbar?

War es hilfreich?

Lösung

__progname nicht Standard ist und daher nicht tragbar, bevorzugt argv[0]. Ich nehme an __progname könnte ein String-Ressource-Lookup den Namen zu erhalten, die auf den Dateinamen nicht abhängig ist, dass Sie läuft es wie. Aber argv[0] geben Sie den Namen sie wirklich lief es wie denen ich mehr nützlich finden.

Andere Tipps

__progname ermöglicht es Ihnen, den Inhalt des argv[] Array zu ändern, während nach wie vor die Programmnamen beibehalten. Einige der gemeinsamen Werkzeuge wie getopt() argv[] ändern, da sie die Argumente verarbeiten.

Für Portabilität, können Sie Ihre eigenen strcopy argv[0] Puffer progname in, wenn Ihr Programm gestartet wird.

Es gibt auch eine GNU-Erweiterung für diese, so dass man den Programmaufruf Namen von außerhalb des Hauptes zugreifen kann (), ohne sie manuell zu speichern. Man könnte besser sein, es manuell zu tun, jedoch; wodurch es tragbar, im Gegensatz zu der GNU-Erweiterung zu verlassen. Dennoch stelle ich hier einen Auszug aus der verfügbaren Dokumentation.

die on-line GNU C Library Handbuch (zugegriffen heute):

"Viele Programme, die, wenn eine Systemaufruf zum Beenden nicht Eingabe vom Terminal gelesen werden entworfen ausfällt. Vereinbarungsgemäß wird die Fehlermeldung von einem solchen Programm sollte mit dem Programmnamen beginnen, sans-Verzeichnisse. Sie diesen Namen finden in den variablen program_invocation_short_name; der vollständige Dateiname wird die Variable program_invocation_name gespeichert

.
  • Variable: char * program_invocation_name Diese Variable der Wert ist der Name, der verwendet wurde, das Programm aufzurufen, im aktuellen Prozess ausgeführt wird. Es ist das gleiche wie argv[0]. Beachten Sie, dass dieser Name nicht unbedingt eine nützliche Datei ist; es enthält oft keine Verzeichnisnamen.

  • Variable: char * program_invocation_short_name Diese Variable der Wert ist der Name, der verwendet wurde, das Programm läuft im aktuellen Prozess aufzurufen, mit entfernt Verzeichnisnamen. (Das heißt, es ist die gleiche wie program_invocation_name minus allem bis zum letzten Schrägstrich, falls vorhanden.)

Die Bibliothek Initialisierungscode setzt diese beiden Variablen auf vor dem Aufruf Haupt.

Portabilität Hinweis: Diese beiden Variablen sind GNU-Erweiterungen. Wenn Sie Ihr Programm wollen mit nicht-GNU Bibliotheken arbeiten, müssen Sie den Wert von argv[0] in Haupt speichern und dann die Verzeichnisnamen selbst abzustreifen. Wir haben diese Erweiterungen, um zu ermöglichen umluftunabhängigem Fehlerbericht Subroutinen zu schreiben, die keine explizite Zusammenarbeit von Haupt erfordern. "

Ich sehe zumindest zwei mögliche Probleme mit argv [0].

Als erstes argv [0] oder argv selbst NULL sein kann, wenn execve () Anrufer sind böse oder unvorsichtig genug. Der Aufruf execve ( „foobar“, NULL, NULL) ist in der Regel eine einfache und unterhaltsame Art und Weise eines mehr als zuversichtlich Programmierer seinen Code zu beweisen, ist nicht SIG11 sicher.

Es muss auch darauf hingewiesen werden, dass argv nicht außerhalb der Haupt definiert werden (), während __progname in der Regel als globalen Variable definiert ist, Sie aus Ihrer Nutzung () Funktion oder sogar vor main () (wie Nicht-Standard heißt verwenden können GCC Bauer).

Es ist ein BSDism, und definitiv nicht tragbar.

__ progname wird nur argv [0] und Beispiele in anderen Antworten zeigen hier die Schwächen der es zu benutzen. Obwohl nicht tragbar entweder bin ich mit Readlink auf / proc / self / exe (Linux, Android) und liest den Inhalt von / proc / self / exefile (QNX).

Wenn Ihr Programm ausgeführt wurde unter Verwendung von, zum Beispiel, einen symbolischen Link, argv [0] wird den Namen dieser Verbindung enthalten.

Ich vermute, dass __progname den Namen der aktuellen Programmdatei enthalten wird.

In jedem Fall argv [0] wird durch den C-Standard definiert. __progname nicht.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top