Est-il prudent d’utiliser getenv () dans des initialiseurs statiques, c’est-à-dire avant main ()?

StackOverflow https://stackoverflow.com/questions/437279

Question

J'ai consulté Stevens et dans le Guide du programmeur Posix , et le mieux que je puisse trouver est

  

Un tableau de chaînes appelé environnement est rendu disponible au début du processus.   Ce tableau est désigné par la variable externe environ , définie comme suit:

     

caractère externe ** environ;

C'est cette variable environ qui m'a fait hésiter. Je veux dire

-Le processus / shell appelant a déjà alloué le bloc de chaînes à zéro terminal

-la variable 'externe' environ est utilisée comme point d'entrée par getenv () .

- ipso facto n'hésitez pas à appeler getenv () dans un initialiseur statique.

Mais je ne trouve aucune garantie que "l'initialisation statique" de environ précède tout le code d'initialisation statique. Est-ce que je réfléchis trop?

Mettre à jour

Sur ma plate-forme (AMD Opteron, Redhat 4, GCC 3.2.3), la définition de LD_DEBUG indique que environ est défini sur . avant , mes initialiseurs statiques sont appelés. C'est une bonne chose à savoir. merci, @codelogic. Mais ce n'est pas nécessairement le résultat que j'obtiendrais sur toutes les plateformes.

De plus, bien que je sois d’accord intuitif avec @ChrisW sur le comportement de la bibliothèque d’exécution C / C ++, il ne s’agit que de mon intuition fondée sur l’expérience. Ainsi, quiconque peut se procurer une citation d'un endroit faisant autorité qui garantit que environ est là avant l'appel des initialiseurs statiques, points bonus!

Était-ce utile?

La solution

Je pense que vous pouvez exécuter votre programme avec LD_DEBUG défini pour afficher l'ordre exact:

LD_DEBUG=all <myprogram>

MODIFIER: Si vous examinez le code source de l'éditeur de liens d'exécution (glibc 2.7), en particulier dans les fichiers:

  • sysdeps / unix / sysv / linux / init-first.c
  • sysdeps / i386 / init-first.c
  • csu / libc-start.c
  • sysdeps / i386 / elf / start.S

vous verrez que argc, argv et environ (alias pour __ environ) sont définis avant que tous les constructeurs globaux soient appelés (les fonctions init). Vous pouvez suivre l’exécution à partir de _start, le point d’entrée réel (start.S). Comme vous l'avez dit, Stevens "Un tableau de chaînes appelé environnement est rendu disponible au début du processus", ce qui suggère que l'attribution d'environnement a lieu au tout début de l'initialisation du processus. Ceci, soutenu par le code de l'éditeur de liens, qui fait la même chose, devrait vous donner une tranquillité d'esprit suffisante: -)

EDIT 2: Il est également intéressant de noter que Environ est défini suffisamment tôt pour que même l'éditeur de liens à l'exécution puisse l'interroger pour déterminer s'il faut ou non générer une sortie verbale (LD_DEBUG).

Autres conseils

Étant donné que la configuration de l'environnement et l'appel des initialiseurs statiques sont des fonctions que l'exécution de la langue doit exécuter avant que main () ne soit invoqué, je ne suis pas sûr que vous trouverez une garantie. ici. C’est-à-dire que je ne suis pas au courant d’une exigence spécifique ici que cela doive fonctionner et que la commande soit garantie avant main () dans, par exemple, le langage ANSI et les spécifications de la bibliothèque ou quoi que ce soit ... .mais je n'ai pas vérifié pour être sûr non plus.

En même temps, je ne suis pas au courant d'une exigence spécifique qui limite les fonctions de bibliothèque d'exécution pouvant être appelées à partir d'un initialiseur statique. Et, plus précisément, cela ressemblerait à un bug d’exécution (pour moi) si vous ne pouviez pas accéder à l’environnement à partir de celui-ci.

Sur cette base, je vote que je m'attendrais à ce que cela fonctionne, est une hypothèse sûre, et les données actuelles semblent corroborer ce raisonnement.

D'après mon expérience, la bibliothèque d'exécution C est initialisée avant que l'exécution n'appelle les initialiseurs de vos variables statiques (vos initialiseurs peuvent donc appeler des fonctions de bibliothèque d'exécution C).

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top