2010-05-08 22 views
22

Lo que he entendido acerca de pasar argumentos a main() desde la línea de comandos es que argc tiene un valor mínimo de 1 y argv [0] siempre tendrá el nombre del programa con su ruta de acceso.¿Cuándo puede argv [0] tener nulo?

Si los argumentos se proporcionan en la línea de comando, entonces argc tendrá un valor mayor que uno y argv 1 a argv [argc-1] tendrá esos argumentos.

Ahora un párrafo al this link dice que

argv [0] será una cadena que contiene el nombre del programa o una cadena nula si eso no es disponible.

Ahora, ¿cómo y cuándo puede argv [0] tener una cadena nula? Me refiero a que el nombre del programa con su ruta siempre estará disponible, entonces ¿cuándo puede ser nulo?

Writer dice que "si no está disponible", pero ¿cuándo y cómo es posible que el nombre del programa no esté disponible?

+1

@ShaunHamman El consenso actual es cerrar por "calidad": http://meta.stackexchange.com/questions/147643/should-i-vote-to-close-a-duplicate-question-even-though-its-much -newer-and-ha Dado que la "calidad" no es medible, simplemente voy por upvotes. ;-) Probablemente se deba a qué pregunta golpear las mejores nuevas palabras clave de Google en el título. –

Respuesta

22

Con la clase exec de llamadas, se especifica el nombre del programa y el programa ejecutable por separado para que pueda configurarlo a NULL entonces.

Pero esa cita es en realidad del estándar ISO (posiblemente parafraseado) y ese estándar cubre una gama terriblemente grande de entornos de ejecución, desde el microcontrolador más pequeño hasta el mainframe z10 Enterprise.

Muchos de esos sistemas integrados estarían en una situación en la que un nombre ejecutable tiene poco sentido.

Desde el último borrador c1x:

El valor de argc será negativo.

El valor argv[argc] será un puntero nulo.

Si el valor de argc es mayor que cero, los miembros de la matriz a través de argv[0]argv[argc-1] incluido deberá contener punteros a cadenas, que se dan los valores de implementación definidos por el entorno de acogida antes de programar la puesta en marcha.

Esto significa que, si argc es cero (y puede ser), argv [0] es NULL.

Pero, incluso cuando argc es no 0, usted no puede obtener el nombre del programa, ya que la norma también establece:

Si el valor de argc es mayor que cero, la cadena apuntada por argv[0] representa el nombre del programa; argv[0][0] será el carácter nulo si el nombre del programa no está disponible desde el entorno de host. Si el valor de argc es mayor que uno, las cadenas apuntadas por argv[1] hasta argv[argc-1] representan los parámetros del programa.

Por lo tanto, no hay ningún requisito bajo el estándar de que se proporcione un nombre de programa. He visto programas que utilizan una amplia selección de opciones para este valor:

  • sin ningún valor (por supuesta seguridad).
  • una mentira flagrante (como sleep por un código malicioso).
  • el nombre del programa real (como sleep).
  • una ligeramente modificada (como -ksh para el shell de inicio de sesión).
  • un nombre descriptivo (por ejemplo, progname - a program for something).
5

Según this mailing list, argv[0] puede ser nulo si argc == 0. Pero no explican cuandoargc podría ser cero. Me gustaría sospechosoargc sería cero en situaciones donde un ejecutable no se inició "normalmente" (es decir, a través de una línea de comando, popen, etc.) - y de hecho, como @paxdiablo mencionado, puede configurar manualmente argv con el exec family of functions , por lo que argc podría ser cero dependiendo de esos argumentos.

Pero, en su Fundamento sección:

primeras propuestas requiere que el valor de argc pasado a main() "uno o más". Esto fue impulsado por el mismo requisito en los borradores del estándar ISO C. De hecho, las implementaciones históricas han pasado un valor de cero cuando no se proporcionan argumentos a la persona que llama de las funciones de ejecución. Este requisito se eliminó del estándar ISO C y posteriormente también se eliminó de este volumen de IEEE Std 1003.1-2001. La redacción, en particular el uso de la palabra debería, requiere que una Aplicación POSIX de Conformidad Estricta transfiera al menos un argumento a la función de ejecución, garantizando así que argc sea uno o más cuando se invoque por dicha aplicación. De hecho, esta es una buena práctica, ya que muchas aplicaciones existentes hacen referencia al argv[0] sin verificar primero el valor de argc.

Así que ahí lo tienen: Aplicaciones POSIX Estrictamente Conformes deben tener argc ser mayor que cero, pero que por lo demás es de ninguna manera garantizado.

Hay un poco más de información sobre el estándar con respecto a argc y argv en la sección Program Startup.

1

Es posible imaginar plataformas donde los programas no tienen nombres, quizás el código simplemente se carga al inicio. En esos, argv [0] podría ser NULL. El estándar C ciertamente permite un valor argc de cero, y dice que argv [argc] debe ser NULL.

0

Ejecutable POSIX ejemplo

a.c

#define _XOPEN_SOURCE 700 
#include <unistd.h> 

int main(void) { 
    char *argv[] = {NULL}; 
    char *envp[] = {NULL}; 
    execve("b.out", argv, envp); 
} 

b.c

#include <stdio.h> 

int main(int argc, char **argv) { 
    if (argc == 0 && argv[0] == NULL) 
     puts("yup"); 
} 

Entonces:

gcc a.c -o a.out 
gcc b.c -o b.out 
./a.out 

Da:

yup 

probado en Ubuntu 16.10.

Cuestiones relacionadas