¿Qué debería devolver main () en C y C++?


¿Cuál es la forma correcta (más eficiente) de definir la función main() en C y C++ - int main() o void main() - y por qué? Si int main() entonces return 1 o return 0?


Hay numerosos duplicados de esta pregunta, incluyendo:

Relacionado:

Author: Community, 2008-10-15

18 answers

El valor devuelto para main debe indicar cómo salió el programa. La salida normal generalmente se representa con un valor de retorno 0 de main. La terminación anormal generalmente se señala con un retorno distinto de cero, pero no hay un estándar para cómo se interpretan los códigos distintos de cero. También como han señalado otros, void main() está explícitamente prohibido por el estándar de C++ y no debe usarse. Las firmas válidas de C++ main son:

int main()

Y

int main(int argc, char* argv[])

Que es equivalente a

int main(int argc, char** argv)

Es también vale la pena señalar que en C++, int main() se puede dejar sin un valor de retorno en cuyo punto por defecto devuelve 0. Esto también es cierto con un programa C99. Está abierto a debate si debe omitirse o no el retorno 0. El rango de firmas principales válidas del programa C es mucho mayor.

Además, la eficiencia no es un problema con la función main. Solo se puede ingresar y dejar una vez (marcando el inicio y la terminación del programa) de acuerdo con el estándar C++. Para C, el caso es diferente y reingresar main() está permitido, pero probablemente debería evitarse.

 478
Author: workmad3,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-01-22 13:49:38

La respuesta aceptada parece estar dirigida a C++, así que pensé en agregar una respuesta que pertenezca a C, y esto difiere de algunas maneras.

ISO/IEC 9899:1989 (C90):

main() debe declararse como:

int main(void)
int main(int argc, char **argv)

O equivalente. Por ejemplo, int main(int argc, char *argv[]) es equivalente al segundo. Además, el tipo de retorno int se puede omitir ya que es un valor predeterminado.

Si una implementación lo permite, main() se puede declarar de otras maneras, pero esto hace que el programa implementación definida, y ya no estrictamente conforme.

El estándar define 3 valores para devolver que son estrictamente conformes (es decir, no se basan en el comportamiento definido por la implementación): 0 y EXIT_SUCCESS para una terminación exitosa, y EXIT_FAILURE para una terminación fallida. Cualquier otro valor no es estándar y su implementación está definida. main() debe tener una declaración explícita return al final para evitar un comportamiento indefinido.

Finalmente, no hay nada malo de un punto de vista estándar con la llamada main() desde un programa.

ISO/IEC 9899:1999 (C99):

Para C99, todo es lo mismo que el anterior excepto:

  • No se puede omitir el tipo de retorno int.
  • Puede omitir la declaración return de main(). Si lo haces, y main() terminado, hay un implícito return 0.
 140
Author: Chris,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-08-05 17:45:56

Entorno estándar alojado en C

Para un entorno alojado (que es el normal), el estándar C11 (ISO/IEC 9899:2011) dice:

5.1.2.2.1 Inicio del programa

La función llamada al inicio del programa se llama main. La aplicación declara no prototipo para esta función. Se definirá con un tipo de retorno de int y no parámetros:

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

O con dos parámetros (referidos aquí como argc y argv, aunque cualquier nombre puede ser se utilizan, ya que son locales a la función en la que se declaran):

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

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

Si se declaran, los parámetros de la función principal obedecerán a lo siguiente: limitaciones:

  • El valor de argc no será negativo.
  • argv[argc] será un puntero nulo.
  • Si el valor de argc es mayor que cero, los miembros de la matriz argv[0] a través de argv[argc-1] inclusive contendrá punteros a cadenas, que se dan valores definidos por el entorno host antes del inicio del programa. El la intención es proporcionar al programa información determinada antes del inicio del programa desde cualquier otro lugar del entorno alojado. Si el entorno host no es capaz de el suministro de cadenas con letras en mayúsculas y minúsculas, la implementación se asegurará de que las cadenas se reciben en minúsculas.
  • 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 en el entorno host. Si el valor de argc es mayor que uno, las cadenas apuntadas por argv[1] hasta argv[argc-1] representar los parámetros del programa.
  • Los parámetros argc y argv y las cadenas apuntadas por la matriz argv deberán ser modificable por el programa, y conservar sus últimos valores almacenados entre el programa inicio y terminación del programa.

10) Así, int puede ser reemplazado por un nombre typedef definido como int, o el tipo de argv puede ser escrito como char **argv, y así sucesivamente.

Terminación del programa en C99 o C11

El valor devuelto desde main() se transmite al 'entorno' de una manera definida por la implementación.

5.1.2.2.3 Programa terminación

1 Si el tipo de retorno de la función main es un tipo compatible con int, la llamada inicial a la función main es equivalente a llamar a la función exit con el valor devuelto por la función main como su argumento;11) alcanzar el } que termina el main la función devuelve un valor de 0. Si el tipo devuelto no es compatible con int, el el estado de terminación devuelto al entorno host es indeterminado.

11) De conformidad con 6.2.4, la vida útil de los objetos con duración de almacenamiento automático declarada en main habrá terminado en el primer caso, incluso cuando no lo habrían hecho en el segundo.

Tenga en cuenta que 0 es obligatorio como 'éxito'. Puedes usar EXIT_FAILURE y EXIT_SUCCESS de <stdlib.h> si lo prefieres, pero 0 está bien establecido, y también 1. Ver también Códigos de salida mayores que 255-posible?.

En C89 (y por lo tanto en Microsoft C), no hay ninguna declaración sobre lo que sucede si la función main() devuelve pero no especifica un valor de retorno; por lo tanto, conduce a un comportamiento indefinido.

7.22.4.4 La función exit

¶5 Finalmente, el control se devuelve al entorno host. Si el valor de status es cero o EXIT_SUCCESS, se devuelve una forma definida por la implementación del status successful termination. Si el valor de status es EXIT_FAILURE, una forma definida por la implementación del estado se devuelve la terminación fallida. De lo contrario, el estado devuelto está definido por la implementación.

Entorno estándar alojado en C++

El estándar C++11 (ISO/IEC 14882:2011) dice:

3.6.1 Función principal [básico.empezar.principal]

¶1 Un programa contendrá una función global llamada main, que es el inicio designado del programa. [...]

¶2 Una implementación no predefinirá el función principal. Esta función no se sobrecargará. Deberá tener un tipo devuelto de tipo int, pero por lo demás su tipo está definido como implementación. Todas las implementaciones permitirá las dos definiciones siguientes de main:

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

Y

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

En la última forma argc será el número de argumentos pasados al programa desde el entorno en el que se ejecuta el programa. Si argc es distinto de cero, estos argumentos se presentarán en argv[0] a través de argv[argc-1] como punteros a los caracteres iniciales de cadenas multibyte terminadas en cero (NTMBSs) (17.5.2.1.4.2) y argv[0] será el puntero al carácter inicial de un NTMBS que representa la nombre utilizado para invocar el programa o "". El valor de argc no será negativo. El valor de argv[argc] será 0. [Nota: Se recomienda añadir cualquier otro parámetro (opcional) después de argv. -final nota ]

¶3 La función main no se utilizará dentro de un programa. El linkage (3.5) of main is implementation-defined. [...]

¶5 Una sentencia return en main tiene el efecto de dejar la función main (destruyendo cualquier objeto con storage duration) y llamando a std::exit con el valor devuelto como argumento. Si el control llega al final de main sin encontrar una sentencia return, el efecto es el de ejecutar

return 0;

El estándar de C++ dice explícitamente " [la función principal] tendrá un tipo de retorno de tipo int, pero por lo demás su tipo es implementation defined", y requiere que las mismas dos firmas que el estándar C sean soportadas como opciones. Por lo tanto, un' void main () ' no está permitido directamente por el estándar de C++, aunque no hay nada que pueda hacer para detener una implementación no estándar que permita alternativas. Tenga en cuenta que C++ prohíbe al usuario llamar a main (pero el estándar C no lo hace).

Hay un párrafo de §18.5 Inicio y terminación en el estándar C++11 que es idéntico al párrafo de §7.22.4.4 La función exit en el estándar C11 (citado anteriormente), aparte de una nota al pie (que simplemente documenta que EXIT_SUCCESS y EXIT_FAILURE se definen en <cstdlib>).

Estándar C-Extensión común

Clásicamente, los sistemas Unix soportan una tercera variante:

int main(int argc, char **argv, char **envp) { ... }

El tercer argumento es una lista terminada en cero de punteros a cadenas, cada uno de los cuales es una variable de entorno que tiene un nombre, un signo igual y un valor (posiblemente vacío). Si no usa esto, todavía puede llegar al entorno a través de ' extern char **environ;'. Durante mucho tiempo, eso no tenía un encabezado que lo declarara, pero el estándar POSIX 2008 ahora requiere que se declare en <unistd.h>.

Esto es reconocido por el estándar C como una extensión común, documentada en el anexo J:

J. 5. 1 Argumentos de entorno

¶1 En un entorno alojado, la función principal recibe un tercer argumento, char *envp[], que apunta a una matriz terminada en cero de punteros a char, cada uno de los cuales apunta a una cadena que proporciona información sobre el entorno para esta ejecución del programa (5.1.2.2.1).

Microsoft C

El compilador Microsoft VS 2010 es interesante. El sitio web dice:

La sintaxis de declaración para main es

 int main();

O, opcionalmente,

int main(int argc, char *argv[], char *envp[]);

Alternativamente, las funciones main y wmain pueden ser declared as returning void (no return value). Si declara main o wmain como returning void, no puede devolver un código de salida al proceso padre o al sistema operativo mediante una instrucción return. Para devolver un código de salida cuando main o wmain se declara como void, debe usar la función exit.

No me queda claro qué sucede (qué código de salida se devuelve al padre o al sistema operativo) cuando un programa con void main() sale - y el sitio web de MS es silencioso demasiado.

Curiosamente, MS no prescribe la versión de dos argumentos de main() que los estándares C y C++ requieren. Solo prescribe una forma de tres argumentos donde el tercer argumento es char **envp, un puntero a una lista de variables de entorno.

La página de Microsoft también enumera algunas otras alternativas - wmain() que toma cadenas de caracteres anchas, y algunas más.

La versión de Microsoft Visual Studio 2005 de esta página no aparece void main() como alternativa. Las versiones de Microsoft Visual Studio 2008 en adelante lo hacen.

Estándar C-Entorno independiente

Como se señaló anteriormente, los requisitos anteriores se aplican a los entornos alojados. Si está trabajando con un entorno independiente (que es la alternativa a un entorno alojado), entonces el estándar tiene mucho menos que decir. Para un entorno independiente, la función llamada al inicio del programa no necesita ser llamada main y no hay restricciones en su tipo de retorno. El estándar dice:

5.1.2 Entornos de ejecución

Se definen dos entornos de ejecución: independiente y alojado. En ambos casos, el inicio del programa se produce cuando una función C designada es llamada por la ejecución ambiente. Todos los objetos con duración de almacenamiento estático deben inicializarse (establecer sus valores iniciales) antes del inicio del programa. La manera y el momento de tal inicialización son de otra manera indeterminado. La terminación del programa devuelve el control al entorno de ejecución.

5.1.2.1 Entorno independiente

En un entorno independiente (en el que la ejecución del programa C puede tener lugar sin ningún beneficio de un sistema operativo), el nombre y el tipo de la función llamada al inicio del programa están definidos por la implementación. Cualquier biblioteca disponible para un programa independiente, que no sea el conjunto mínimo requerido por la cláusula 4, son implementación-definida.

El efecto de la terminación del programa en un entorno independiente está definido por la implementación.

La referencia cruzada a la cláusula 4 Conformidad se refiere a esto:

¶5 A strictly conforming program utilizará solo las características del lenguaje y la biblioteca especificadas en este Estándar Internacional.3) No deberá producir una producción que dependa de cualquier producto no especificado, indefinido, o comportamiento definido por la implementación, y no excederá ningún límite mínimo de implementación.

¶6 Las dos formas de implementación conforme son alojadasy independientes. A conforming hosted implementation shall accept any strictly conforming program. Una implementación independiente conforme aceptará cualquier programa estrictamente conforme en el que el uso de las características especificadas en la cláusula de biblioteca (cláusula 7) se limite a el contenido de las cabeceras estándar <float.h>, <iso646.h>, <limits.h>, <stdalign.h>, <stdarg.h>, <stdbool.h>, <stddef.h>, <stdint.h>, y <stdnoreturn.h>. Una implementación conforme puede tener extensiones (incluyendo funciones adicionales de biblioteca), siempre que no alteren el comportamiento de ningún programa estrictamente conforme.4)

¶7 Un programa conforme es uno que es aceptable para una implementación conforme.5)

3) Un programa estrictamente conforme puede utilizar entidades condicionales (véase 6.10.8.3) siempre que el uso esté protegido por una directiva de preprocesamiento de inclusión condicional apropiada utilizando la macro relacionada. Por ejemplo:

#ifdef __STDC_IEC_559__ /* FE_UPWARD defined */
    /* ... */
    fesetround(FE_UPWARD);
    /* ... */
#endif

4) Esto implica que una implementación conforme no reserva otros identificadores que los explícitamente reservados en esta Norma Internacional.

5) Los programas estrictamente conformes están destinados a ser lo más portátiles posible entre las implementaciones conformes. Los programas conformes pueden depender de las características no portátiles de una implementación conforme.

Es notable que la única cabecera requerida de un entorno independiente que realmente define cualquier función es <stdarg.h> (e incluso esas pueden ser - y a menudo son - solo macros).

Estándar C++ - Entorno independiente

Así como el estándar C reconoce tanto el entorno alojado como el independiente, también lo hace el estándar C++. (Citas de ISO / IEC 14882:2011.)

1.4 Cumplimiento de la implementación [intro.cumplimiento]

¶7 Se definen dos tipos de implementaciones: una implementación alojada y una implementación independiente . Para una implementación alojada, este Estándar Internacional define el conjunto de bibliotecas disponibles. A independiente la implementación es aquella en la que la ejecución puede tener lugar sin el beneficio de un sistema operativo, y tiene un conjunto definido por la implementación de bibliotecas que incluyen ciertas bibliotecas de soporte de idiomas (17.6.1.3).

¶8 Una implementación conforme puede tener extensiones (incluyendo funciones de biblioteca adicionales), siempre que no alteren el comportamiento de ningún programa bien formado. Se requieren implementaciones para diagnosticar programas que utilice tales extensiones que están mal formadas de acuerdo con esta Norma Internacional. Una vez hecho esto, sin embargo, pueden compilar y ejecutar tales programas.

¶9 Cada uno la implementación incluirá documentación que identifique todas las construcciones soportadas condicionalmente que no soporta y defina todas las características específicas de la localización.3

3) Esta documentación también define el comportamiento definido por la implementación; véase 1.9.

17.6.1.3 Implementaciones independientes[cumplimiento]

Se definen dos tipos de implementaciones: hosted y freestanding (1.4). Para una implementación alojada, esto El Estándar Internacional describe el conjunto de encabezados disponibles.

Una implementación independiente tiene un conjunto de encabezados definido por la implementación. Este conjunto incluirá al menos las cabeceras que figuran en el cuadro 16.

La versión suministrada del encabezado <cstdlib> declarará al menos las funciones abort, atexit, at_quick_exit, exit, y quick_exit (18.5). Los demás encabezados enumerados en esta tabla deberán cumplir los mismos requisitos que para una implementación alojada.

Tabla 16-Encabezados C++ para implementaciones independientes

Subclause                           Header(s)
                                    <ciso646>
18.2  Types                         <cstddef>
18.3  Implementation properties     <cfloat> <limits> <climits>
18.4  Integer types                 <cstdint>
18.5  Start and termination         <cstdlib>
18.6  Dynamic memory management     <new>
18.7  Type identification           <typeinfo>
18.8  Exception handling            <exception>
18.9  Initializer lists             <initializer_list>
18.10 Other runtime support         <cstdalign> <cstdarg> <cstdbool>
20.9  Type traits                   <type_traits>
29    Atomics                       <atomic>

¿Qué hay de usar int main() en C?

El estándar §5.1.2.2.1 del estándar C11 muestra la notación preferida - int main(void) - pero también hay dos ejemplos en el estándar que muestran int main(): §6.5.3.4 ¶8 y §6.7.6.3 ¶20. Ahora bien, es importante señalar que los ejemplos no son "normativos"; son solo ilustrativos. Si hay errores en los ejemplos, no afecta directamente al texto principal del estándar. Dicho esto, son fuertemente indicativos del comportamiento esperado, por lo que si el estándar incluye int main() en un ejemplo, sugiere que int main() no está prohibido, incluso si no es la notación preferida.

6.5.3.4 Los operadores sizeof y _Alignof

¶8 EJEMPLO 3 En este ejemplo, se calcula el tamaño de una matriz de longitud variable y se devuelve desde una función:

#include <stddef.h>

size_t fsize3(int n)
{
    char b[n+3]; // variable length array
    return sizeof b; // execution time sizeof
}
int main()
{
    size_t size;
    size = fsize3(10); // fsize3 returns 13
    return 0;
}
 102
Author: Jonathan Leffler,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-10-05 00:43:05

Creo que main() debería volver ya sea EXIT_SUCCESS o EXIT_FAILURE. Se definen en stdlib.h

 57
Author: dmityugov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-09-28 03:31:37

Tenga en cuenta que los estándares C y C++ definen dos tipos de implementaciones: independiente y alojada.

  • Entorno alojado en C90

    Formularios permitidos1:

    int main (void)
    int main (int argc, char *argv[])
    
    main (void)
    main (int argc, char *argv[])
    /*... etc, similar forms with implicit int */
    

    Comentarios:

    Los dos primeros se indican explícitamente como las formas permitidas, los otros se permiten implícitamente porque C90 permitió "implicit int" para los parámetros de tipo y función de retorno. No se permite ninguna otra forma.

  • C90 independiente medio ambiente

    Se permite cualquier forma o nombre de main2.

  • C99 hosted environment

    Formularios permitidos3:

    int main (void)
    int main (int argc, char *argv[])
    /* or in some other implementation-defined manner. */
    

    Comentarios:

    C99 eliminó "implicit int" por lo que main() ya no es válido.

    Se ha introducido una frase extraña y ambigua "o de alguna otra manera definida por la implementación". Esto puede ser interpretado como "los parámetros a int main() pueden variar "o como" main puede tener cualquier forma definida por la implementación".

    Algunos compiladores han optado por interpretar el estándar de la última manera. Podría decirse que no es fácil afirmar que no se ajustan estrictamente citando la norma en sí misma, ya que es ambigua.

    Sin embargo, permitir formas completamente salvajes de main() fue probablemente (?) no es la intención de esta nueva frase. La justificación C99 (no normativa) implica que la oración se refiere a parámetros adicionales a int main 4.

    Sin embargo, la sección para la terminación del programa de entorno alojado continúa discutiendo sobre el caso en el que main no devuelve int 5. Aunque esa sección no es normativa sobre cómo debe declararse main, definitivamente implica que main podría declararse de una manera completamente definida por la implementación incluso en sistemas alojados.

  • C99 entorno independiente

    Se permite cualquier forma o nombre de main 6.

  • C11 hosted environment

    Formularios permitidos7:

    int main (void)
    int main (int argc, char *argv[])
    /* or in some other implementation-defined manner. */
    
  • C11 entorno independiente

    Se permite cualquier forma o nombre de main8.


Tenga en cuenta que int main() nunca se listó como una forma válida para cualquier implementación alojada de C en cualquiera de las versiones anteriores. En C, a diferencia de C++, () y (void) tienen significados diferentes. El primero es un obsoleto característica que se puede eliminar del idioma. Véase C11 direcciones futuras del lenguaje:

6.11.6 Declaradores de funciones

El uso de declaradores de funciones con paréntesis vacíos (no declaradores de tipo de parámetro de formato prototipo) es una característica obsoleta.


  • Entorno alojado en C++03

    Formularios permitidos9:

    int main ()
    int main (int argc, char *argv[])
    

    Comentarios:

    Observe el paréntesis vacío en la primera forma. C++ y C son diferentes en este caso, porque en C++ esto significa que la función no toma parámetros. Pero en C significa que puede tomar cualquier parámetro.

  • C++03 entorno independiente

    El nombre de la función llamada al inicio está definido por la implementación. Si se nombra main() debe seguir las formas indicadas10:

    // implementation-defined name, or 
    int main ()
    int main (int argc, char *argv[])
    
  • Entorno alojado en C++11

    Formularios permitidos 11:

    int main ()
    int main (int argc, char *argv[])
    

    Comentarios:

    El texto de la norma ha sido cambiado, pero tiene el mismo significado.

  • C++11 entorno independiente

    El nombre de la función llamada al inicio está definido por la implementación. Si se nombra main() debe seguir las formas indicadas12:

    // implementation-defined name, or 
    int main ()
    int main (int argc, char *argv[])
    

Referencias

  1. ANSI X3.159-1989 2.1.2.2 Entorno alojado. "Programa inicio"

    La función llamada al inicio del programa se llama main. El la implementación no declara ningún prototipo para esta función. Será definido con un tipo de retorno de int y sin parámetros:

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

    O con dos parámetros (referidos aquí como argc y argv, aunque cualquier nombre puede ser utilizado, ya que son locales a la función en la que se declaran):

    int main(int argc, char *argv[]) { /* ... */ }
    
  2. ANSI X3. 159-1989 2.1.2.1 Independiente medio ambiente:

    En un entorno independiente (en el que la ejecución del programa C puede tomar lugar sin ningún beneficio de un sistema operativo), el nombre y el tipo de la función llamada al inicio del programa están definidos por la implementación.

  3. ISO 9899: 1999 5.1.2.2 Entorno alojado - > 5.1.2.2.1 Inicio del programa

    La función llamada al inicio del programa se llama main. El la implementación no declara ningún prototipo para esta función. Se será definido con un tipo de retorno de int y sin parámetros:

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

    O con dos parámetros (referidos aquí como argc y argv, aunque cualquier nombre puede ser utilizado, ya que son locales a la función en la que se declaran):

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

    O equivalente; 9) o en alguna otra implementación-definida manera.

  4. Rationale for International Standard - Programming Languages - C, Revisión 5.10. 5.1.2.2 Entorno alojado> > 5.1.2.2.1 Inicio del programa

    El comportamiento de los argumentos a main, y de la interacción de exit, main y atexit (ver §7.20.4.2) ha sido codificado para frenar alguna variedad no deseada en la representación de argv strings, y en el significado de los valores devueltos por main.

    La especificación de argc y argv como argumentos para main reconoce una amplia práctica previa. se requiere que argv[argc] sea 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.

    Principal es la única función que puede portable declararse con cero o dos argumentos. (El número de argumentos de otras funciones debe coincidir exactamente entre invocación y definición.) Este caso especial simplemente reconoce la práctica generalizada de dejar los argumentos a main cuando el programa no accede a las cadenas de argumentos del programa. Mientras que muchas implementaciones soportan más de dos argumentos, tal práctica no está bendecida ni prohibida por el Estándar; un programa que define main con tres argumentos no es estrictamente conforme (ver §J. 5.1.).

  5. ISO 9899: 1999 5.1.2.2 Entorno alojado > > 5.1.2.2.3 Terminación del programa

    Si el tipo de retorno de la función main es un tipo compatible con int, un retorno de la llamada inicial a la función main es equivalente a llamar a la función exit con el valor devuelto por la función main como su argumento;11) alcanzar el } que termina la función principal devuelve un valor de 0. Si el tipo devuelto no es compatible con int, el estado de terminación devuelto al entorno host no se especifica.

  6. ISO 9899: 1999 5.1.2.1 Entorno independiente

    En un entorno independiente (en el que la ejecución del programa C puede tener lugar sin ningún beneficio de un sistema operativo), el nombre y el tipo de la función llamada al inicio del programa están definidos por la implementación.

  7. ISO 9899: 2011 5.1.2.2 Entorno alojado - > 5.1.2.2.1 Inicio del programa

    Esta sección es idéntica a la C99 citada anteriormente.

  8. ISO 9899: 1999 5.1.2.1 Entorno independiente

    Esta sección es idéntica a la C99 citada anteriormente.

  9. ISO 14882: 2003 3.6.1 Función principal

    Una aplicación no definirá previamente la función principal. Esta función no se sobrecargará. Tendrá un tipo de retorno de tipo int, pero por lo demás su tipo está definido por la implementación. Todas las implementaciones permitirán las dos definiciones siguientes de main:

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

    Y

    int main(int argc, char* argv[]) { /* ... */ }
    
  10. ISO 14882: 2003 3.6.1 Función principal

    Está definido por la implementación si se requiere un programa en un entorno independiente para definir una función principal.

  11. ISO 14882:2011 3.6.1 Función principal

    Una aplicación no definirá previamente la función principal. Esta función no se sobrecargará. Tendrá un tipo de retorno de tipo int, pero por lo demás su tipo está definido por la implementación. Todas las implementaciones deberán permitir ambos

    - una función de () que devuelve int y

    - una función de (int, puntero a puntero a char) que devuelve int

    Como el tipo de main (8.3.5).

  12. ISO 14882:2011 3.6.1 Función principal

    Esta sección es idéntica a la de C++03 citada anteriormente.

 29
Author: Lundin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-02-21 07:08:17

Devuelve 0 en caso de éxito y no cero en caso de error. Este es el estándar utilizado por UNIX y DOS scripting para averiguar lo que sucedió con su programa.

 27
Author: Lou Franco,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-10-15 12:16:51

Tenga en cuenta que,a pesar de que está devolviendo un int, algunos sistemas operativos (Windows) truncan el valor devuelto a un solo byte (0-255).

 7
Author: Ferruccio,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-10-15 15:22:13

main() en C89 y K & R C los tipos de retorno no especificados son por defecto 'int'.

return 1? return 0?
  1. Si no escribe una instrucción return en int main(), el cierre { devolverá 0 por defecto.

  2. return 0 o return 1 será recibido por el proceso primario. En un shell entra en una variable shell, y si está ejecutando su programa desde un shell y no utiliza esa variable, entonces no necesita preocuparse por el valor devuelto de main().

Ver ¿Cómo puede Obtengo lo que mi función principal ha devuelto?.

$ ./a.out
$ echo $?

De esta manera se puede ver que es la variable $? la que recibe el byte menos significativo del valor devuelto de main().

En Unix y scripting de DOS, return 0 en caso de éxito y distinto de cero por error se devuelven normalmente. Este es el estándar utilizado por Unix y DOS scripting para averiguar lo que sucedió con su programa y controlar todo el flujo.

 7
Author: Jeegar Patel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-02-21 00:14:24

El valor devuelto puede ser utilizado por el sistema operativo para comprobar cómo se cerró el programa.

El valor de retorno 0 generalmente significa OK en la mayoría de los sistemas operativos (los que se me ocurren de todos modos).

También se puede comprobar cuando se llama a un proceso usted mismo, y ver si el programa salió y terminó correctamente.

Es NO solo una convención de programación.

 4
Author: Yochai Timmer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-03-13 15:14:22

El valor devuelto de main() muestra cómo salió el programa. Si el valor devuelto es zero significa que la ejecución tuvo éxito, mientras que cualquier valor distinto de cero representará que algo salió mal en la ejecución.

 3
Author: Fahad Uddin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-03-13 15:14:52

Tenía la impresión de que standard especifica que main no necesita un valor de retorno ya que un retorno exitoso estaba basado en el sistema operativo (cero en uno podría ser un éxito o un error en otro), por lo tanto, la ausencia de retorno era una señal para que el compilador insertara el retorno exitoso en sí.

Sin embargo, normalmente devuelvo 0.

 2
Author: graham.reeds,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-10-15 12:42:47

Devolver 0 debería decirle al programador que el programa ha terminado con éxito el trabajo.

 2
Author: Vamsi Pavan Mahesh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-03-13 15:18:42

Lo que se debe devolver depende de lo que se quiera hacer con el ejecutable. Por ejemplo, si está utilizando su programa con un shell de línea de comandos, entonces necesita devolver 0 para un éxito y un no cero para un error. Entonces usted sería capaz de utilizar el programa en shells con procesamiento condicional dependiendo del resultado de su código. También puede asignar cualquier valor distinto de cero según su interpretación, por ejemplo, para errores críticos diferentes puntos de salida del programa podrían terminar un programa con diferentes valores de salida, y que está disponible para el shell que llama que puede decidir qué hacer inspeccionando el valor devuelto. Si el código no está destinado a usarse con shells y el valor devuelto no molesta a nadie, entonces podría omitirse. Yo personalmente uso la firma int main (void) { .. return 0; .. }

 1
Author: phoxis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-09-28 03:32:13

Si realmente tiene problemas relacionados con la eficiencia de devolver un entero de un proceso, probablemente debería evitar llamar a ese proceso tantas veces que este valor devuelto se convierta en un problema.

Si está haciendo esto (llama a un proceso tantas veces), debe encontrar una manera de poner su lógica directamente dentro de la persona que llama, o en un archivo DLL, sin asignar un proceso específico para cada llamada; las asignaciones de procesos múltiples le traen el problema de eficiencia relevante en este caso.

En detalle, si solo desea saber si devolver 0 es más o menos eficiente que devolver 1, podría depender del compilador en algunos casos, pero genéricamente, asumiendo que se leen desde la misma fuente (local, campo, constante, incrustado en el código, resultado de la función, etc.).) requiere exactamente el mismo número de ciclos de reloj.

 1
Author: Luca C.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-03-13 15:12:55

¿Cuál es la forma correcta (más eficiente) de definir la función main() en C y C++ - int main() o void main() - y por qué?

Esas palabras "(más eficiente)" no cambian la pregunta. A menos que esté en un entorno independiente, hay una forma universalmente correcta de declarar main(), y es como devolver int.

¿Qué debería devolver main() en C y C++?

No Es lo que debe main() volver, es lo que no main() return. main() es, por supuesto, una función que otra persona llama. Usted no tiene ningún control sobre el código que llama main(). Por lo tanto, debe declarar main() con una firma de tipo correcto para que coincida con su llamante. Usted simplemente no tiene ninguna opción en el asunto. No tienes que preguntarte qué es más o menos eficiente, o qué es mejor o peor estilo, o algo así, porque la respuesta ya está perfectamente definida, para ti, por los estándares C y C+. Sólo tienes que seguir ellos.

If int main () entonces devuelve 1 o devuelve 0?

0 para el éxito, distinto de cero para el fracaso. Una vez más, no es algo que necesites (o llegar a) elegir: está definido por la interfaz a la que se supone que debes conformarte.

 1
Author: Steve Summit,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-10-03 21:56:28

En C++ la función main debe ser declarada como int main() y no void main() ya que el compilador lanza un error en el caso de void main. La principal función puede tomar cualquier número de argumentos como int main(int k,int l,int arr[]) o int main(void).

#include <iostream>
using namespace std;

int main(void) {
    // your code goes here
    cout<<"a";
    return 0;
}

Salida:

Success #stdin #stdout 0s 4416KB
a

Llegando a la parte de retorno debería devolver solo 0 si no el compilador lanza un error. por ejemplo, si devuelve 1, obtendrá la salida deseada, pero también lanza un tiempo de ejecución error.

Ejemplo

#include <iostream>
using namespace std;

int main(int k,float m,char g, int arr[]) {
    // your code goes here
    k=0;
    cout<<k;
    g='a';
    cout<<g;
    cout<<"a";
    return 1;
}

Salida:

Runtime error   #stdin #stdout 0s 4448KB
0aa
 1
Author: Somit,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-02-23 05:26:23

Aquí hay una pequeña demostración del uso de códigos de retorno...

Cuando se utilizan las diversas herramientas que el terminal Linux proporciona, se puede usar el código de retorno, por ejemplo, para el manejo de errores después de que el proceso se haya completado. Imagine que el siguiente archivo de texto myfile está presente:

Este es un ejemplo para comprobar cómo funciona grep.

Cuando ejecuta el comando grep se crea un proceso. Una vez que está a través (y no se rompió) devuelve algunos código entre 0 y 255. Por ejemplo:

$ grep order myfile

Si lo haces

$ echo $?
$ 0

Obtendrá un 0. ¿Por qué? Porque grep encontró una coincidencia y devolvió un código de salida 0, que es el valor habitual para salir con éxito. Vamos a comprobarlo de nuevo, pero con algo que no está dentro de nuestro archivo de texto y por lo tanto no se encontrará ninguna coincidencia:

$ grep foo myfile
$ echo $?
$ 1

Dado que grep no pudo hacer coincidir el token " foo " con el contenido de nuestro archivo, el código devuelto es 1 (este es el caso habitual cuando se produce un error, pero como se indicó anteriormente, tiene muchos valores para elegir).

Ahora el siguiente script bash (simplemente escríbalo en un terminal Linux) , aunque muy básico, debería dar alguna idea del manejo de errores:

$ grep foo myfile
$ CHECK=$?
$ [ $CHECK -eq 0] && echo 'Match found'
$ [ $CHECK -ne 0] && echo 'No match was found'
$ No match was found

Después de la segunda línea no se imprime nada al terminal ya que "foo" hizo que grep devolviera 1 y comprobamos si el código de retorno de grep era igual a 0. La segunda sentencia condicional hace eco de su mensaje en la última línea ya que es true debido a CHECK = = 1.

Como puedes ver si a veces es esencial ver lo que ha devuelto (por el valor de retorno de main ()).

 0
Author: rbaleksandar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-03-13 15:36:48

Omitir return 0

Cuando un programa C o C++ llega al final de main el compilador generará automáticamente código para devolver 0, por lo que no hay necesidad de poner return 0; explícitamente al final de main.

Nota: cuando hago esta sugerencia, es casi invariablemente seguida por uno de dos tipos de comentarios: "No sabía eso."o" ¡Es un mal consejo!"Mi razonamiento es que es seguro y útil confiar en el comportamiento del compilador explícitamente apoyado por el estándar. Para C, desde C99; véase ISO/IEC 9899: 1999 sección 5.1.2.2.3:

[...] un retorno de la llamada inicial a la función main es equivalente a llamar a la función exit con el valor devuelto por la función main como su argumento; alcanzar el } que termina la función main devuelve un valor de 0.

Para C++, desde el primer estándar en 1998; véase ISO/IEC 14882: 1998 sección 3.6.1: {[14]]}

Si el control llega al final de main sin encontrar un return, el efecto es el de ejecutar return 0;

Todas las versiones de ambos estándares desde entonces (C99 y C++98) han mantenido la misma idea. Dependemos de funciones miembro generadas automáticamente en C++, y pocas personas escriben sentencias return; explícitas al final de una función void. Las razones en contra de omitir parecen reducirse a "se ve raro". Si, como yo, tienes curiosidad sobre la justificación del cambio al estándar C lee esto pregunta. También tenga en cuenta que a principios de la década de 1990 esto se consideraba "práctica descuidada" porque era un comportamiento indefinido (aunque ampliamente apoyado) en el momento.

Así que yo abogo por omitirlo; otros no están de acuerdo (¡a menudo con vehemencia!) En cualquier caso, si encuentras código que lo omite, sabrás que está explícitamente soportado por el estándar y sabrás lo que significa.

 0
Author: Edward,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:02:46