2009-07-27 11 views
21

La norma ISO 1998 C++ especifica que no usar explícitamente una instrucción return en la parte principal es equivalente a usar return 0. Pero, ¿qué sucede si una implementación tiene un código estándar diferente de "error", por ejemplo -1?¿Por qué el valor de retorno predeterminado de main es 0 y no EXIT_SUCCESS?

¿Por qué no utilizar la macro estándar EXIT_SUCCESS que se reemplazará por 0 o -1 o cualquier otro valor según la implementación?

C++ parece forzar la semántica del programa, que no es el papel de un lenguaje que solo debería describir cómo se comporta el programa. Además, la situación es diferente para el valor de retorno de "error": solo EXIT_FAILURE es una bandera de terminación de "error" estándar, sin valor explícito, como "1", por ejemplo.

¿Cuáles son las razones de estas elecciones?

Respuesta

34

Volviendo a cero de main() es esencialmente lo mismo que lo que está preguntando. La devolución del cero desde main() no tiene que devolver cero al entorno de host.

Desde el modelo de documento C90/C99/C++ 98:

Si el valor de estado es cero o EXIT_SUCCESS, una forma definida por la implementación del estado se devuelve la terminación exitosa.

+4

solo para aclarar, que se especifica para la función exit(), y 3.6.1: 5 estados tat el efecto de regresar de main es dejar main y luego llamar a exit(). Entonces sí, tienes razón. :) – jalf

+1

En otras palabras, cero y 'EXIT_SUCCESS' son valores de retorno equivalentes, por lo que no importa cuál sea el estándar requerido que se devuelva por defecto. –

+0

Muy interesante, significa que el estándar C++ no fuerza el "código de éxito" del host. Devolver "0" de un programa C++ no garantiza que el sistema host recibirá "0" y significa que el comportamiento de la declaración de retorno C++ podría ser diferente de lo que el programador especificó: "return 0" podría estar en una implementación "reemplazado" por "retorno 1"? – Pragmateek

4

0 es el código de salida estándar (correcto) en todos los sistemas POSIX, ¡y en todos los sistemas que conozco! Creo que ha sido así sinc time begain (o al menos desde que Unix lo hizo ...) Así que es por esta razón que diría.

¿Qué sistema sabes que es diferente?

+2

En mi humilde opinión, si no hubiera ningún * sistema * que prefiriera un valor diferente, y el * idioma * definiera cuál era el valor de retorno principal exitoso, esto haría que el idioma entrara en conflicto en ese sistema. Además de eso, no puedes probar un teorema dando ejemplos. – xtofl

+2

"EXIT_STATUS podría tiene un valor diferente de 0, y de hecho lo hizo en VAX/VMS en un punto en el tiempo": tomado de http://bytes.com/groups/c/215177-exit_success-guaranteed-always -zero – xtofl

+0

Es cierto que "0" como indicador de éxito es un estándar "de facto". Pero convertirlo en el estándar para C++ obliga a los sistemas host a usarlo para ser una implementación "isocompatible". Considerando que el uso de una constante estándar como EXIT_SUCCESS garantiza que la semántica, "todo está bien", no está acoplada con los detalles de implementación, "0 significa éxito, 1 falla ...". – Pragmateek

5

La norma es simplemente hacer una determinación sobre cuál debe ser el valor cuando no se establece explícitamente. Depende de los desarrolladores establecer explícitamente el valor de retorno o asumir una semántica adecuada para el valor predeterminado. No creo que el lenguaje intente forzar ninguna semántica a los desarrolladores.

+0

El valor predeterminado no debe ser determinado por la capa C++ sino por el sistema. Por ejemplo, si un programa se escribe primero en C++, "0" será el código de éxito estándar; luego, si se reescribe en otro idioma para el cual "1" es el código estándar de éxito predeterminado, se rompería el comportamiento de los demás programas/usuarios que lo usan. Considerando que si los dos idiomas tienen una macro EXIT_SUCCESS que será administrada por el sistema host todo funcionará bien. La macro sería reemplazada por el compilador por su valor en el sistema: "0" para posix, "1" para otras ... – Pragmateek

0

Si también estaba pensando en por qué el código de error para el éxito es 0 en lugar de cualquier otro valor, agregaría que podría haber sido históricamente por razones de rendimiento, ya que comparando con 0 ha sido más rápido (creo que en las arquitecturas pueden ser las mismas que con cualquier número) y generalmente no se busca un código de error en particular, solo si fue exitoso o si hubo algún error (por lo que tiene sentido usar la comparación más rápida para eso).

+1

No creo que este sea el motivo para usar 0 como indicador de éxito - Creo que la razón es que generalmente hay más de una manera de fallar, por lo que es necesario que haya más de un código de falla. –

+0

Eso es cierto, pero no contradice lo que he dicho. Si ERROR_SUCCESS fue 1 (o lo que sea) todavía tiene todos los otros números para indicar diferentes tipos de fallas. – fortran

3

0 como el código de retorno para el éxito, y los enteros positivos como errores es el estándar en C y Unix. Se eligió este esquema porque normalmente a uno no le importa por qué un programa sucedió a, solo que sí lo hizo. Por otro lado, hay muchas formas en que un programa puede fallar con un error, y a menudo uno está interesado en esta información. Por lo tanto, tiene sentido usar un valor escalar para el éxito, y un rango de valores para el error. El uso de enteros positivos es una convención de C que ahorra memoria, ya que permiten que el código de error se defina como un int sin signo.

18

¡En realidad, return 0 no devolverá necesariamente 0! Estoy citando el estándar C aquí, porque es lo que mejor sé.

Sobre return en main():

5.1.2.2.3 terminación Programa

Si el tipo de retorno de la función principal es un tipo compatible con int, un retorno de la llamada inicial al main función es equivalente a llamar a la función exit con el valor devuelto por la función main como argumento;

Sobre exit():

7.20.4.3 La función de salida
Sinopsis

#include <stdlib.h> 
void exit(int status); 

[...]
Por último, el control se devuelve al entorno de acogida. Si el valor de status es cero o EXIT_SUCCESS, se devuelve una forma definida por la implementación del estado finalización exitosa devuelta.

+0

Siempre es agradable ver a alguien explicando el estándar de una manera comprensible. Aún así, poder elegir entre el literal cero y EXIT_SUCCESS es equivalente a usar dos definiciones posiblemente conflictivas. ¿Tengo razón en pensar eso? – xtofl

+4

¿De dónde ven que proviene este conflicto? Es responsabilidad del compilador hacerlo funcionar. La forma más fácil es #define EXIT_SUCCESS 0, pero esa es solo una opción. – MSalters

+0

@Bastien: Gracias, sus comentarios completan la explicación de Michael. – Pragmateek

1

Los estándares de lenguaje de computadora dicen qué tiene que ver un programa escrito en el idioma y qué sucederá. En este caso, los estándares C y C++ dicen que devolver 0 señales de éxito, entre otras cosas.

Las implementaciones de lenguaje permiten que los programas se ejecuten en implementaciones particulares. Es el trabajo del implementador descubrir cómo hacer que las E/S funcionen de acuerdo con el estándar, o darle al sistema operativo el código de resultado correcto.

Lo que hace un programa y lo que el sistema operativo ve no tiene que ser lo mismo. Todo lo que es necesario es que el programa funcione como dice el estándar en el sistema operativo dado.

2

OS/360 y sucesores utilizan un código de salida numérica, 0 siendo por lo general éxito, 4 de advertencias (como un compilador que genera mensaje de advertencia), 8 para el error, y 12 para todo malos errores (como ser incapaz para abrir SYSPRINT, la unidad de salida estándar).

+0

Interesante información histórica. – Pragmateek

1

Al navegar cstdlib que terminó con dos líneas:

#define EXIT_SUCCESS 0 
#define EXIT_FAILURE 1 

Así EXIT_SUCCESS es igual a 0, y es igual a EXIT_FAILURE1, lo que significa que no importa, pensó.

Comprueba Linux (OpenSuse) y termina con lo mismo.

+1

Para ser pedante: estas definiciones son solo para su plataforma, otra plataforma podría usar una convención diferente; aunque creo que ahora son universales. :) – Pragmateek

+0

@Pragmateek Por supuesto, lo es. Este código es de Windows, pero creo que es lo mismo para Linux. Sin embargo, leeré de Linux y Android y veremos con qué terminaré. –

Cuestiones relacionadas