2011-12-04 11 views
5

Estaba escribiendo un programa rápido para calcular algunas cosas cuando encontré la declaración de declaración/salida para el programa C.¿Es necesario devolver un valor en Main()?

He declarado main() ser del tipo int, así que tendría que devolver un número entero, o mi programa no se compilaría correctamente. Sin embargo, ¿es aceptable hacer main a Boolean o incluso void?

Sé que la manera estándar de crear un programa C es devolver un valor para que cualquier problema se pueda resolver, entre otras cosas, pero ¿no funcionaría un Boolean de la misma manera? Además, ¿podría salirse con la suya al declararlo void y no tener problemas con el sistema operativo que aún ejecuta mi programa después de que se ha terminado?

Gracias por toda la ayuda.

+0

No es necesario, pero es obligatorio. – Philip

Respuesta

6

estándar El C99 dice: (§5.1.2.2.1 programa de inicio)

La función llamada al inicio del programa se denomina principal. La implementación no declara el prototipo para esta función. Que se definirá con un tipo retorno de int y sin parámetros:

int main(void) { /* ... */ } 

o con dos parámetros (denominados aquí como argc y argv, aunque los nombres pueden ser utilizado, ya que son locales a la función en la que están declarados):

int main(int argc, char *argv[]) { /* ... */ } 

o equivalente; o de alguna otra manera definida por la implementación.

Por lo tanto, en un entorno alojado, int es el único tipo de devolución válido y estándar. Sin embargo, las implementaciones pueden definir otros puntos de entrada.

Tenga en cuenta que la sección §5.1.2.2.3 Programa de Terminación tiene esta:

Si el tipo de retorno de la función principal es un tipo compatible con int, un retorno de la llamada inicial al función principal es equivalente a llamar a la función de salida con el valor devuelto por la función principal como argumento; llegando a} que finaliza la función principal devuelve un valor de 0. Si el tipo de devolución no es compatible con int, el estado de terminación devuelto al entorno del host no está especificado.

Así que la omisión de un retorno de main es legal en C99, siempre y cuando su main devuelve un int.
(Pero las versiones anteriores del estándar C no tenían esa excepción para main - no devolver ningún valor (o alcanzar el } final sin declaración de devolución) provoca "el estado de terminación devuelto al entorno host [por definir] . ".)

+0

'o de alguna otra manera definida por la implementación' -> esto deja mucho espacio para la interpretación :-) – jdehaan

+0

@jdehaan: No realmente; "definido por la implementación" significa algo que está explícitamente documentado por la implementación. –

+1

Vale la pena mencionar que en C90, al llegar a '}' se devuelve un estado indefinido. –

0

El código que llama a main() espera que devuelva int (o call exit()). No puede cambiar el código que llama a main() (es parte del sistema operativo o tiempo de ejecución), así que será mejor que devuelva int.

2

Aquí hay un link que podría ser de su interés. Parece que la respuesta a tu pregunta no es tan directa. También he visto compiladores (MS Visual C) que aceptan void como tipo de devolución.

+0

¡Muy interesante! – nmagerko

+1

Hay una diferencia entre implementaciones "alojadas" e "independientes". El OP debe considerarse una implementación alojada, por lo que debe apegarse al estándar. Borland, Microsoft y Herb Schildt pueden contaminar el lenguaje con su propia semántica, pero no deberían llamarlo "estándar". – wildplasser

0

El tipo de devolución debe ser int, como se cubre en otras respuestas. Sin embargo, su suposición de que debe devolver un valor debido a esto es incorrecta, main es una excepción. El estándar C99 proporciona esto, por lo que está perfectamente bien implementar main sin usar return.

0

En ANSI C, main() generalmente tiene un tipo de devolución de int, pero en realidad puede ser definido por la implementación; esto significa que diferentes compiladores y plataformas aceptan firmas diferentes, pero int main() y int main (int, char**) son garantizados por el estándar para estar bien formados.

Es diferente de otras funciones no anuladas, ya que no necesita una declaración return. En el caso de que no se suministre ninguno, y el tipo de devolución se especifique como int, entonces el programa se compila como si hubiera un implícito return 0; después de la última instrucción en main().

La parte pertinente de la norma:

5.1.2.2.3 Programa de terminación

Si el tipo de retorno de la función main es un tipo compatible con int, una return desde la llamada inicial a la función main es equivalente a llamar a la función exit con el valor devuelto por el main funciona como su argumento; llegando al } que termina la función main devuelve un valor de 0. Si el tipo de devolución no es compatible con int, el estado de terminación devuelto al entorno del host no está especificado.

No me hagáis esto, pero en K + R, sin embargo, las cosas eran un poco más flojo, y yo creo que ni siquiera es necesario especificar un tipo de retorno, por lo que es en realidad un main() { } programa de K + R válido

+0

'int main (void)', no 'int main()'. Y en K & R C (y en 1989 ANSI C/1990 ISO C), si omite el tipo de retorno, el valor predeterminado es 'int'. Esa regla se eliminó en el estándar ISO C de 1999. Nunca es una buena idea aprovecharlo. –

+0

Derecha, por supuesto. Creo que mi C++ se está mostrando ... – Halfbin

1

Resumen: No necesariamente tiene que hacerlo, pero debería hacerlo.

En C90, llegando al final de main() sin ejecutar una declaración return "el estado de terminación devuelto al entorno de host no está definido". En al menos un sistema que he usado, el estado devuelto es 1, que en ese sistema indica que el programa falló.

C99 agregó una nueva regla, diciendo que al llegar al final main() devuelve 0. (C++ tiene la misma regla). No todos los compiladores implementan completamente C99, y los que a menudo no se comportan como compiladores C99 por defecto .

Los únicos valores portátiles se puede volver a main() son 0, EXIT_SUCCESS y EXIT_FAILURE (estos dos últimos se definen en <stdlib.h> 0 y EXIT_SUCCESS indican que el programa tuvo éxito (y EXIT_SUCCESS se define generalmente como 0);. EXIT_FAILURE indica que el programa falló. return 1; es común, pero no portátil; he trabajado en un sistema (VMS), donde un estado de terminación de 1 indica éxito. Si desea que su programa sea portátil, use EXIT_FAILURE para indicar el error; eso es lo es para. Algunos sistemas y programas definen otros códigos de estado específicos del sistema o específicos de la aplicación.

Para la portabilidad (y, en mi humilde opinión, el estilo), es mejor hacer un return 0; explícito al final de main(), aunque no es obligatorio en todas las circunstancias. Es mucho más fácil agregar esa línea de código (que es, en el peor de los casos, inofensiva) que perder tiempo para determinar si lo necesita.

Tenga en cuenta que las definiciones correctas para main() son:

int main(void) { /* ... */ } 

y

int main(int argc, char *argv[]) { /* ... */ } 

o equivalente (por ejemplo, puede escribir char **argv en lugar de char *argv[]). Es cuestionable si int main() { /* ... */ } es válido, por razones sutiles no entraré aquí. De nuevo, es más fácil agregar la palabra clave void que perder tiempo para determinar si lo necesita.

Muchos libros y tutoriales usan void main() o void main(void). Un compilador particular puede elegir permitir esto, pero no es portátil. Ver void main en un libro o tutorial es una buena señal de que el autor no conoce muy bien el estándar C, y que debe buscar algo más para estudiar.

Cuestiones relacionadas