por - para que sirve int argc char*argv[]
¿Es seguro usar el puntero argv globalmente? (6)
¿Es seguro usar el puntero argv
globalmente? ¿O hay una circunstancia en la que puede ser inválido?
Es decir: ¿Es seguro este código?
char **largs;
void function_1()
{
printf("Argument 1: %s/r/n",largs[1]);
}
int main(int argc,char **argv)
{
largs = argv;
function_1();
return 1;
}
¿Es seguro usar el puntero argv globalmente?
Esto requiere un poco más de aclaración. Como dice la especificación C11
en el capítulo §5.1.2.2.1, Inicio del programa
[..] .. con dos parámetros (referidos aquí como
argc
yargv
, aunque se puede usar cualquier nombre, ya que son locales a la función en la que están declarados)
Esto significa que las variables en sí tienen un alcance limitado a main()
. Ellos mismos no son globales .
Nuevamente la norma dice:
Los parámetros
argc
yargv
y las cadenas señaladas por la matriz argv serán modificables por el programa y conservarán sus últimos valores almacenados entre el inicio del programa y la terminación del programa.
Eso significa que la vida útil de estas variables es hasta que main()
finalice la ejecución.
Por lo tanto, si está utilizando una variable global para mantener el valor de main()
, puede usar esos elementos globales de manera segura para acceder al mismo en cualquier otra función (es).
Debe ser seguro siempre que la función main()
no salga. Algunos ejemplos de cosas que pueden suceder después de las salidas main()
son:
- Destructores de variables globales y estáticas.
- Hilos que se ejecutan más tiempo que
main()
No se debe utilizar argv
almacenado en esos.
La referencia no dice nada que pueda dar una razón para suponer que la duración de los argumentos para la función main()
difiere de las reglas generales para la duración de los argumentos de la función.
Mientras el puntero argv
sea válido, el tiempo de ejecución de C / C ++ debe garantizar que el contenido al que apunta este puntero es válido (por supuesto, a menos que algo corrompa la memoria). Por lo tanto, debe ser seguro usar el puntero y el contenido durante mucho tiempo. Después de que main()
regrese, tampoco hay razón para que el tiempo de ejecución de C / C ++ mantenga el contenido válido. Por lo tanto, el razonamiento anterior se aplica tanto al puntero como al contenido al que apunta.
Puede pasarlos como parámetros o almacenarlos en global variables
. Mientras no regrese de main
e intente procesarlos en un controlador atexit
o el destructor de una variable en el ámbito global, todavía existen y estarán bien para acceder desde cualquier ámbito.
Sí, es seguro utilizar argv
globalmente; Puede usarlo como usaría cualquier char**
en su programa. El estándar C99 incluso especifica esto:
Los parámetros
argc
yargv
y las cadenas señaladas por la matrizargv
serán modificables por el programa y conservarán sus últimos valores almacenados entre el inicio del programa y la terminación del programa.
El estándar de C ++ no tiene un párrafo similar, pero el mismo está implícito sin ninguna regla en contrario.
Tenga en cuenta que C ++ y C son idiomas diferentes y que solo debe elegir uno para hacer su pregunta.
sí, es seguro para el éter C o C ++, porque no había ningún hilo después de que finalice main.
Este hilo en el grupo de noticias comp.lang.c.moderado analiza el tema en detalle desde un punto de vista estándar de C, incluida una cita que muestra que el contenido de las matrices argv (en lugar del propio puntero argv, si, por ejemplo, tomó una dirección &argv
y almacenaron eso) duran hasta la "finalización del programa", y una afirmación de que es "obvio" que la finalización del programa aún no se ha producido de manera relevante mientras se ejecutan las funciones registradas en atexit:
El programa no ha finalizado durante el procesamiento de funciones registradas en atexit. Pensamos que eso era bastante obvio.
(No estoy seguro de quién es Douglas A. Gwyn, pero parece que "nosotros" significa el comité estándar de C?)
El contexto de la discusión fue principalmente sobre el almacenamiento de una copia del puntero argv[0]
(nombre del programa).
El texto estándar de C relevante es 5.1.2.2.1:
Los parámetros argc y argv y las cadenas señaladas por la matriz argv serán modificables por el programa y conservarán sus últimos valores almacenados entre el inicio del programa y la terminación del programa.
Por supuesto, C ++ no es C, y su estándar puede diferir sutilmente en este tema o no abordarlo.