Ist char *envp[] als drittes Argument für main() portable
Lesezeit: 3 Minuten
Sangeeth Saravanaraj
Um eine Umgebungsvariable in a zu erhalten C Programm könnte man folgendes verwenden:
getenv()
extern char **environ;
Aber andere als die oben genannten, ist die Verwendung char *envp[] als drittes Argument zu main() um die Umgebungsvariablen als Teil des Standards zu betrachten?
Die Funktion getenv ist die einzige, die von der C-Norm spezifiziert wird. Die Funktion putenvund die extern environ sind POSIX-spezifisch.
BEARBEITEN
Das main Parameter envp wird von POSIX nicht spezifiziert, aber weitgehend unterstützt.
Eine alternative Methode für den Zugriff auf die Umgebungsliste besteht darin, ein drittes Argument für die Funktion main() zu deklarieren:
int main(int argc, char *argv[], char *envp[])
Dieses Argument kann dann genauso behandelt werden wie environ, mit dem Unterschied, dass sein Geltungsbereich lokal zu main() ist. Obwohl diese Funktion auf UNIX-Systemen weit verbreitet ist, sollte ihre Verwendung vermieden werden, da zusätzlich zur Umfangsbeschränkung es ist nicht in SUSv3 angegeben.
Beachten Sie, dass der C-Standard dies als gängige Alternative anerkennt – sogar C89 erwähnte es in Anhang G (Portabilitätsprobleme); es befindet sich in Anhang J (Portabilitätsprobleme) sowohl in C99 als auch in C11.
– Jonathan Leffler
17. Mai 2014 um 20:15 Uhr
Es funktioniert nicht mit (mindestens) z/OS 2.4 und xlc/c99/c89 auf dem IBM Mainframe. Es gibt eine POSIX-Lösung.
– ben
23. März 2021 um 7:33 Uhr
skyel
Es ist nicht tragbar. *envp[] ist eine traditionelle UNIX-Sache, und nicht alle modernen UNIX-Systeme implementieren sie.
Als Randnotiz können Sie auch auf envp zugreifen, indem Sie einen Zeigerdurchlauf durchführen *argv[]überfließend … aber ich denke nicht, dass das in Betracht gezogen werden kann sicher Programmierung. Wenn Sie sich die Prozessspeicherkarte ansehen, werden Sie das sehen envp[] ist gleich oben argv[].
Und Sie können auch an der Umgebung vorbeigehen und sie untersuchen auxv… 😉
– R.. GitHub HÖR AUF, EIS ZU HELFEN
25. April 2012 um 18:35 Uhr
Was wird normalerweise in auxv gespeichert, weil ich mich die anderen Tage nur gefragt habe, warum die Felder nach envp konstant sind (zwischen den Läufen)?
– skyl
25. April 2012 um 20:05 Uhr
Hinein sehen elf.h für die Makros, die mit beginnen AT_. Einige der interessanteren Dinge sind AT_SECURE, AT_RANDOM, AT_EXECFN, AT_HWCAP, und die uid/gid diejenigen. Ansonsten sind sie hauptsächlich für den dynamischen Linker und den libc-Init-Code von Interesse. Das Format von auxv ist ein Paar von Systemwortgrößen-Ganzzahlen, von denen die erste eine der ist AT_ Konstanten (ein Tag) und der zweite davon ist der Wert, der diesem Tag zugeordnet ist (möglicherweise ein Zeiger, abhängig vom Tag).
– R.. GitHub HÖR AUF, EIS ZU HELFEN
26. April 2012 um 3:14 Uhr
Wie wäre es, wenn Sie einen Zeiger verwenden, um das Ende von argv zu finden und einen Schritt weiter zu gehen? char **find = argv, **envp; while(*find) find++; envp = find + 1; Wahrscheinlich undefiniertes Verhalten, da ein Betriebssystem nicht garantiert Umgebungsdaten nach dem letzten Argument von argv platziert …
– Braden Best
27. November 2015 um 20:47 Uhr
Traditionellere / idiomatischere und prägnantere Version des letzten Kommentars: char **envp = argv; while(*envp++);
– mtraceur
24. Oktober 2021 um 7:53 Uhr
pmg
Der Standard beschreibt zwei Formate für main (siehe 5.1.2.2.1 im C99-Standard (pdf))
a) int main(void)
und
b) int main(int argc, char **argv) oder gleichwertig
und es ermöglicht Implementierungen, andere Formate zu definieren (die ein drittes Argument zulassen können)
c) oder auf eine andere implementierungsdefinierte Weise.
Eine Implementierung kann bieten weitere Formate für mainaber diese beiden sind die einzigen, die garantiert in jeder gehosteten Implementierung vorhanden sind.