c++ c unix posix environment

c++ - ¿Es seguro usar getenv() en inicializadores estáticos, es decir, antes de main()?



unix posix (3)

En mi experiencia, la biblioteca de tiempo de ejecución de C se inicializa antes de que el tiempo de ejecución invoque los inicializadores de sus variables estáticas (y por lo tanto sus inicializadores pueden llamar a las funciones de biblioteca de tiempo de ejecución de C).

Busqué en Stevens , y en la Guía del programador de Posix , y lo mejor que puedo encontrar es

Una serie de cadenas llamada entorno está disponible cuando comienza el proceso. Esta matriz está apuntada por la variable externa environ , que se define como:

extern char **environ;

Es esa variable de entorno lo que me tiene vacilante. quiero decir

-El proceso / shell llamante ya ha asignado el bloque de cadenas terminadas nulas

-el entorno de la variable ''externa'' se usa como el punto de entrada por getenv () .

- ipso facto no dude en llamar a getenv () dentro de un inicializador estático.

Pero no puedo encontrar ninguna garantía de que la ''inicialización estática'' del entorno preceda a todos los demás códigos de inicialización estáticos. ¿Estoy pensando demasiado en esto?

Actualizar

En mi plataforma (AMD Opteron, Redhat 4, GCC 3.2.3), establecer LD_DEBUG muestra que el entorno se establece antes de que se llamen mis inicializadores estáticos. Esto es algo bueno de saber; gracias, @codelogic. Pero no es necesariamente el resultado que obtendría en todas las plataformas.

Además, aunque estoy de acuerdo intuitivamente con @ChrisW en el comportamiento de la biblioteca de tiempo de ejecución de C / C ++, esta es solo mi intuición basada en la experiencia. Entonces, cualquiera que pueda llegar con una cita de un lugar autorizado que garantice que el entorno está allí antes de que se llamen inicializadores estáticos, ¡puntos extra!


Creo que puede ejecutar su programa con LD_DEBUG configurado para ver el orden exacto:

LD_DEBUG=all <myprogram>

EDITAR: Si observa el código fuente del enlazador en tiempo de ejecución (glibc 2.7), específicamente en los archivos:

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

Verás que argc, argv y environ (alias para __ environ) se establecen antes de llamar a cualquier constructor global (las funciones init). Puede seguir la ejecución comenzando desde _start, el punto de entrada real (start.S). Como mencionó Stevens, "una serie de cadenas llamadas el entorno está disponible cuando comienza el proceso" , lo que sugiere que la asignación del entorno ocurre al comienzo de la inicialización del proceso. Esto respaldado por el código del enlazador, que hace lo mismo, debería darle suficiente tranquilidad :-)

EDIT 2: También vale la pena mencionar es que el entorno se establece lo suficientemente temprano como para que incluso el vinculador de tiempo de ejecución pueda consultarlo para determinar si se genera o no una salida exhaustiva (LD_DEBUG).


Dado que tanto la configuración del entorno como la invocación de los inicializadores estáticos son funciones que el lenguaje de ejecución tiene que realizar antes de invocar a main (), no estoy seguro de que encuentre una garantía aquí. Es decir, no estoy al tanto de un requisito específico aquí que esto tenga que funcionar y que la orden esté garantizada antes de main () en, por ejemplo, el lenguaje ANSI y las especificaciones de la biblioteca o cualquier cosa ... pero no revisé para asegurarse de que cualquiera.

Al mismo tiempo, no conozco un requisito específico que restrinja las funciones de biblioteca en tiempo de ejecución que se pueden invocar desde un inicializador estático. Y, más al punto, se sentiría como un error en tiempo de ejecución (para mí) si no pudieras acceder al entorno desde uno.

Sobre esta base, voto que esperaría que esto funcione, es una suposición segura, y los datos actuales parecen apoyar esta línea de razonamiento.