c++ - smart - ¿Cuál fue la razón para hacer que `return 0` al final de` main` sea opcional?
smart contracts ethereum (2)
Comenzando con el estándar C99, se requiere que el compilador genere el equivalente de un return 0
o un return EXIT_SUCCESS
si no se proporciona un retorno al final de main
. También hubo un cambio correspondiente e idéntico al estándar de lenguaje C ++ en ese mismo momento. Me interesan las razones de ambos y supongo que era poco probable que fueran cambios completamente separados y no relacionados.
Mi pregunta es:
¿Cuál fue la razón documentada para este cambio?
Una respuesta ideal citaría fuentes autorizadas tanto para C como para C ++, por lo que he etiquetado la pregunta en ambos idiomas.
Tenga en cuenta que a diferencia de la pregunta ¿Cuáles son las razones para / contra de devolver 0 de main en ISO C ++? , No estoy pidiendo consejo sobre si escribir el return 0
en mis programas, estoy preguntando por qué se cambiaron los estándares de idioma.
Para ayudar a entender el propósito de la pregunta, aquí hay un poco más del contexto:
- Entender por qué se hizo un cambio es útil para decidir cómo usarlo.
- Las razones se incluyen frecuentemente dentro de la norma misma. Por ejemplo, el estándar C90 incluye muchas notas al pie explicativas, como la nota al pie 36 que comienza, "La intención de esta lista ..."
He estudiado las normas buscando la respuesta por mí mismo antes de preguntar aquí, pero no encontré la respuesta. Me pidieron que ayudara a escribir estándares de codificación para ambos lenguajes para un grupo de programadores y quería asegurarme de que entiendo por qué existe esta función para poder explicar su uso con precisión a otros.
El documento oficial de justificación para C99 apenas aborda esto. Parece que exit(0)
convirtió en el valor predeterminado para el flujo de control fuera del final de main porque se dio semántica portátil significativa a exit(0)
.
Aquí están las dos secciones relevantes:
5.1.2.2.1 Inicio del programa
El comportamiento de los argumentos a
main
y de la interacción deexit
,main
yatexit
(véase §7.20.4.2) se ha codificado para frenar algunas variaciones no deseadas en la representación de cadenasargv
y en el significado de los valores devueltos pormain
.La especificación de
argc
yargv
como argumentos a main reconoce la práctica previa extensa.
argv[argc]
debe ser un puntero nulo para proporcionar una comprobación redundante para el final de la lista, también sobre la base de la práctica común.
main
es la única función que se puede declarar de forma portátil con cero o dos argumentos. (El número de argumentos de otras funciones debe coincidir exactamente entre la invocación y la definición.) Este caso especial simplemente reconoce la práctica generalizada de dejar de lado los argumentos cuando el programa no accede a las cadenas de argumentos del programa. Si bien muchas implementaciones admiten más de dos argumentosmain
, tal práctica no está bendecida ni prohibida por el Estándar; un programa que define main con tres argumentos no es estrictamente conforme (vea §J.5.1.).La redirección de E / S de línea de comando no es obligatoria por el Estándar, ya que se consideró que era una característica del sistema operativo subyacente en lugar del lenguaje C.
y
7.20.4.3 La función de salida
El argumento para
exit
es una indicación de estado devuelta al entorno de invocación. En el sistema operativo UNIX, un valor de cero es el código de retorno exitoso de un programa. Como el uso de C se ha extendido más allá de UNIX, laexit(0)
menudo se ha mantenido como un idioma que indica una terminación exitosa , incluso en sistemas operativos con diferentes sistemas de códigos de retorno. Este uso se reconoce así como estándar. Nunca ha habido una manera portátil de indicar una terminación no exitosa, ya que los argumentos paraexit
están definidos por la implementación. La macroEXIT_FAILURE
se agregó a C89 para proporcionar dicha capacidad.EXIT_SUCCESS
se agregóEXIT_SUCCESS
.Aparte de las llamadas codificadas explícitamente por un programador, la
exit
se invoca en el retorno desdemain
. Por lo tanto, al menos en este caso, el cuerpo deexit
no puede asumir la existencia de ningún objeto con duración de almacenamiento automático, excepto aquellos declarados en laexit
.El Comité consideró la adición de
_exit
, pero la rechazó por motivos de incompatibilidad con la especificación POSIX en la que se basa. Por ejemplo, una preocupación expresada es que_exit
se especificó como una forma de salir de un manejador de señales sin disparar otra señal, pero esa no es la forma en que_exit
comporta en los entornos POSIX. El Comité no quiso dar a los programadores este tipo de falsas esperanzas. (Pero vea §7.20.4.4 para C99.)
En la sección 5.1.2.2.3 del programa The New C Standard , el autor Derek Jones comenta sobre estas líneas del estándar C99:
alcanzando el} que termina la función principal devuelve un valor de 0
es:
El estándar finalmente tiene que inclinarse a las prácticas existentes descuidadas.
Lo que indica que el fundamento era abordar las prácticas de programación deficientes con respecto a devolver explícitamente un valor desde main
. Antes de esto, el estado devuelto no estaba definido.
Indica que muchas implementaciones ya lo implementaron incluso en C90, por lo que el hecho de que este cambio ya refleje una implementación común también probablemente ayudó.