¿Debo devolver EXIT_SUCCESS o 0 desde main ()?


124

Es una pregunta simple, pero sigo viendo respuestas contradictorias: ¿debería volver la rutina principal de un programa C ++ 0o EXIT_SUCCESS?

#include <cstdlib>
int main(){return EXIT_SUCCESS;}

o

int main(){return 0;}

¿Son exactamente lo mismo? ¿ EXIT_SUCCESSSolo debe usarse con exit()?

Pensé EXIT_SUCCESSque sería una mejor opción porque otro software puede considerar cero como un fracaso, pero también escuché que si regresa 0, el compilador es capaz de cambiarlo a un valor diferente de todos modos.


¿Responde esto a tu pregunta? stackoverflow.com/questions/1188335/…
Blastfurnace

2
Esta respuesta sobre C90 parafrasea el estándar, 0y EXIT_SUCCESSambos se interpretan como un éxito.
ta.speot.is

Responderé aquí porque siento que alguien más lo leerá en el futuro. Básicamente hay muchos paradigmas sobre cómo se ve la "C correcta". Algunos paradigmas prefieren usar literales sobre macros, por ejemplo, en lugar de pasar NULL como argumento, pueden pasar (const char *) 0 para indicar que no es solo un nulo, pero si no fuera nulo, debería ser un puntero de caracteres constante. Otros paradigmas prefieren ser independientes del tipo y al usar tipos de macro, pueden evitar tener que cambiar su base de código cuando las cosas cambian radicalmente. Por ejemplo, muchos -
Dmitry

@Dmitry <continuado> Las definiciones de tipo de API de Windows no son correctas en las plataformas más nuevas, pero como eran macros, tenían una manera fácil de cambiar todos los tipos a los que funcionan redefiniendo la macro, y muchos de estos tipos simplemente se escalaron por definición (por ejemplo, int es diferente en diferentes plataformas). Para resumir, use cosas como EXIT_SUCCESS si el código de retorno es importante y puede cambiar en el futuro; de lo contrario, devolver 0 puede parecer un número mágico, pero sigue siendo una convención estándar perfectamente válida. el código de error es principalmente para programas para canalizar resultados de números de uno a otro, -
Dmitry

@Dmitry <continúa> el uso de códigos de error para depurar su programa es un poco débil ya que si devuelve 0, es información bastante inútil, excepto en algunos casos cuando hay errores no manejados en un programa que pueden hacer que el programa se rompa en silencio, y usted necesita para verificar si regresó normalmente (0) o si ocurrió un error silencioso. El retorno de número es más útil para canalizar 0..255 de un programa a otro en función de sus entradas; de lo contrario, no hay razón para pensarlo: devuelva 0 o use un main precompilado que alinee una llamada "init" vacía para no visualmente molestarte con un retorno inútil.
Dmitry

Respuestas:


151

EXIT_FAILURE, ya sea en una declaración de devolución maino como argumento para exit(), es la única forma portátil de indicar un error en un programa C o C ++. exit(1)en realidad puede indicar una terminación exitosa en VMS, por ejemplo

Si va a usar EXIT_FAILUREcuando su programa falla, entonces también podría usarlo EXIT_SUCCESScuando tenga éxito, solo por el bien de la simetría.

Por otro lado, si el programa nunca señala una falla, puede usar cualquiera 0o EXIT_SUCCESS. Ambos están garantizados por el estándar para indicar la finalización exitosa. (Es casi imposible que EXIT_SUCCESSpueda tener un valor distinto de 0, pero es igual a 0 en cada implementación de la que he oído hablar).

El uso 0tiene la pequeña ventaja de que no necesita #include <stdlib.h>en C, o #include <cstdlib>en C ++ (si está usando una returninstrucción en lugar de llamar exit()), pero para un programa de cualquier tamaño significativo, incluirá stdlib directa o indirectamente de todas formas.

Para el caso, en C comenzando con el estándar de 1999, y en todas las versiones de C ++, llegar al final de main()lo implícito de return 0;todos modos, por lo que es posible que no necesite usar ninguno 0o EXIT_SUCCESSexplícitamente. (Pero al menos en C, considero que un estilo explícito return 0;es mejor).

(Alguien preguntó sobre OpenVMS. No lo he usado en mucho tiempo, pero como recuerdo, los valores de estado impares generalmente denotan éxito, mientras que los valores pares denotan fallas. La implementación de C se asigna 0a 1, lo que return 0;indica una terminación exitosa. Otros valores se pasan sin cambios , por lo que return 1;también indica una terminación exitosa. EXIT_FAILUREtendría un valor par distinto de cero).


@KeithThompson, ¿podría aclarar su respuesta con respecto a VMS (OpenVMS?). No está clara la relación EXIT_SUCCESS / EXIT_FAILURE con 0 y 1. En su lugar, explicaría los valores pares / impares.
malat

@malat: ¿Realmente usas VMS?
Keith Thompson

No, nunca lo usé. Estaba buscando una respuesta canónica, ya que wikipedia usaba una redacción diferente .
malat

1
@Rhymoid: Esto está especificado por C, no por POSIX.
Keith Thompson

1
@DeanP: 0y EXIT_SUCCESSno se garantiza que tengan el mismo valor (lo mencioné en mi respuesta), pero ambos denotan una terminación exitosa. EXIT_SUCCESSes estilísticamente mejor si también lo estás usando EXIT_FAILURE, pero exit(0)está bien.
Keith Thompson

25

No importa. Ambos son lo mismo.

Cotizaciones estándar de C ++:

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


12
No le importa al compilador, pero puede ser importante por estilo.
celtschk

2
@celtschk: La cuestión del estilo se basa en la percepción, también conocida como no estandarizada, por lo que no cuenta como una diferencia. Solo puede comparar manzanas con manzanas, no manzanas con peras.
Alok Save

3
No hay garantía de eso EXIT_SUCCESS == 0. Por otro lado, no hay una buena razón para que no lo sea.
Keith Thompson

@KeithThompson: ¿por qué no hay garantía de que EXIT_SUCCESS == 0.? Por favor explícalo más claramente.
Destructor

2
@PravasiMeet: un sistema puede tener más de un valor que indica éxito.
Keith Thompson

11

0 es, por definición, un número mágico. EXIT_SUCCESS es casi universalmente igual a 0, felizmente. Entonces, ¿por qué no simplemente regresar / salir 0?

salir (EXIT_SUCCESS); es abundantemente claro en significado.

salida (0); por otro lado, es contraintuitivo de alguna manera. Alguien que no esté familiarizado con el comportamiento de shell podría suponer que 0 == falso == malo, al igual que cualquier otro uso de 0 en C. Pero no, en este caso especial, 0 == éxito == bueno. Para los desarrolladores más experimentados, no será un problema. Pero, ¿por qué tropezar con el chico nuevo sin ninguna razón?

tl; dr: si hay una constante definida para su número mágico, casi nunca hay una razón para no usar la constante en primer lugar. Es más fácil de buscar, a menudo más claro, etc. y no le cuesta nada.


Creo que sus comentarios sobre las personas que esperan que 0 sea automáticamente malo está fuera de lugar. Muchas API usan 0 para el éxito y no 0 para el fracaso, incluso en stdlib. Por ejemplo stdlib ( fclose(), setvbuf(), ...), POSIX ( listen(), pthread_create(), pipe(), ...), y muchas, muchas otras bibliotecas (por ejemplo OpenGL [ glGetError()], zlib [ deflate()/ inflate()/ ...], SDL [ SDL_CreateWindowAndRenderer()/ ...], y más).
Tim Čas

2
Claro, hay otros casos en los que 0 se usa para 'éxito', pero tiene razón en que es confuso.
Paul Wintz

10

Esta es una historia interminable que refleja los límites (un mito) de "interoperabilidad y portabilidad sobre todo".

Lo que el programa debe devolver para indicar "éxito" debe definirse por quién recibe el valor (el sistema operativo o el proceso que invocó el programa) no por una especificación de lenguaje.

Pero a los programadores les gusta escribir código de "manera portátil" y, por lo tanto, inventan su propio modelo para el concepto de "sistema operativo" que define los valores simbólicos a devolver.

Ahora, en un escenario de muchos a muchos (donde muchos idiomas sirven para escribir programas en muchos sistemas), la correspondencia entre la convención de lenguaje para el "éxito" y el sistema operativo (que nadie puede garantizar que sea siempre el mismo) ser manejado por la implementación específica de una biblioteca para una plataforma objetivo específica.

Pero, desafortunadamente, estos conceptos no estaban tan claros en el momento en que se implementó el lenguaje C (principalmente para escribir el núcleo UNIX), y los gigagramos de libros donde se escribieron diciendo "retorno 0 significa éxito", ya que eso era cierto en el sistema operativo en esa vez tener un compilador de C.

A partir de entonces, nunca se hizo una estandarización clara sobre cómo se debería manejar dicha correspondencia. C y C ++ tienen su propia definición de "valores de retorno", pero nadie otorga una traducción adecuada del sistema operativo (o mejor: ninguna documentación del compilador dice nada al respecto). 0 significa éxito si es cierto para UNIX - LINUX y -por razones independientes- también para Windows, y esto cubre el 90% de las "computadoras de consumo" existentes, que - en la mayoría de los casos - ignoran el valor de retorno (para que podamos discutir durante décadas, ¡pero nadie lo notará!)

Dentro de este escenario, antes de tomar una decisión, haga estas preguntas: - ¿Me interesa comunicarle algo a mi interlocutor sobre mi existencia? (Si siempre devuelvo 0 ... no hay ninguna pista detrás de todo) - ¿Mi persona que llama tiene convenciones sobre esta comunicación? (Tenga en cuenta que un solo valor no es una convención: eso no permite ninguna representación de información)

Si ambas respuestas son no, probablemente la buena solución es no escribir la declaración de devolución principal. (Y deje que el compilador decida, con respecto al objetivo, está trabajando).

Si no hay una convención establecida 0 = el éxito cumple con la mayoría de las situaciones (y el uso de símbolos puede ser problemático si introducen una convención).

Si existen convenciones, asegúrese de utilizar constantes simbólicas que sean coherentes con ellas (y garantice la coherencia de las convenciones, no la coherencia de valores, entre plataformas).


4

Una vez que comienza a escribir código que puede devolver una miríada de estados de salida, comienza #definea usarlos todos. En este caso EXIT_SUCCESStiene sentido en el contexto de no ser un " número mágico ". Esto hace que su código sea más legible porque cualquier otro código de salida lo será EXIT_SOMETHING. Si simplemente escribe un programa que regresará cuando esté hecho, return 0es válido y probablemente incluso más limpio porque sugiere que no hay una estructura de código de retorno sofisticada.


0

Lo que devuelve de un programa es solo una convención.

No, no puedo pensar en ninguna circunstancia en la que "EXIT_SUCCESS" no sea ​​"0".

Personalmente, recomendaría "0".

EN MI HUMILDE OPINIÓN...


1
He estado programando C ++ durante 10 años y todavía no recuerdo si 0 significa éxito o fracaso en términos de valores de retorno.
lahjaton_j

@lahjaton_j lo entiendo. Piensa que es porque es contra intuitivo: 0es falso y muchas funciones regresan 0en caso de falla / no hacen nada.
significado-asuntos


-5

Algunos compiladores pueden crear problemas con esto: en un compilador de Mac C ++, EXIT_SUCCESS funcionó bien para mí, pero en un compilador de Linux C ++ tuve que agregar cstdlib para saber qué es EXIT_SUCCESS. Aparte de eso, son uno y lo mismo.


Quise decir que en una Mac EXIT_SUCCESS funcionó sin incluir cstdlib.
Ambidiestro el

44
Si se EXIT_SUCCESStrabajó sin incluir ninguno <stdlib.h>o <cstdlib>, algún otro encabezado debe haberlo definido, directa o indirectamente. En C ++, es común para encabezados estándar a #includeotros encabezados estándar. Si esto se compila sin error: int main() { return EXIT_SUCCESS; }entonces su compilador probablemente tenga errores.
Keith Thompson
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.