2010-11-17 45 views
121

¿Cuál es la firma correcta de la función main en C++? ¿Cuál es el tipo de devolución correcto y qué significa devolver un valor desde main? ¿Cuáles son los tipos de parámetros permitidos y cuáles son sus significados?¿Cuál es la declaración correcta de main?

¿Es específico de este sistema? ¿Han cambiado esas reglas con el tiempo? ¿Qué pasa si los violo?

+0

Esto está muy estrechamente relacionado con, o un duplicado de, [¿Qué debe 'main' return en C y C++] (http://stackoverflow.com/questions/204476/what-sho uld-main-return-in-c-and-c/18721336 # 18721336). –

+0

@JonathanLeffler No es broma ... se agregó a la lista de duplicados en [revisión 6] (http://stackoverflow.com/revisions/204476/6) hace aproximadamente 8 meses. – fredoverflow

Respuesta

151

La función main debe declararse como una función no miembro en el espacio de nombres global. Esto significa que no puede ser una función miembro estática o no estática de una clase, ni puede colocarse en un espacio de nombres (incluso el espacio de nombre sin nombre).

El nombre main no está reservado en C++, excepto como una función en el espacio de nombres global. Puede declarar otras entidades con el nombre main, que incluyen, entre otras cosas, clases, variables, enumeraciones, funciones miembro y funciones que no son miembro, no en el espacio de nombres global.

Puede declarar una función denominada main como una función miembro o en un espacio de nombres, pero dicha función no sería la función main que designa dónde se inicia el programa.

La función main no se puede declarar como static o inline. Tampoco puede ser sobrecargado; solo puede haber una función llamada main en el espacio de nombres global.

La función main no se puede utilizar en su programa: no se le permite llamar a la función main desde ningún lugar de su código, ni se le permite tomar su dirección.

El tipo de retorno de main debe ser int. No se permite ningún otro tipo de devolución (esta regla está en negrita porque es muy común ver programas incorrectos que declaran main con un tipo de devolución de void; esta es probablemente la norma más infringida con respecto a la función main).

Hay dos declaraciones de main que deben ser permitidos:

int main()    // (1) 
int main(int, char*[]) // (2) 

En (1), no hay parámetros.

En (2), hay dos parámetros y que convencionalmente se denominan argc y argv, respectivamente. argv es un puntero a una matriz de cadenas C que representan los argumentos del programa. argc es la cantidad de argumentos en la matriz argv.

Normalmente, argv[0] contiene el nombre del programa, pero este no es siempre el caso. argv[argc] se garantiza que es un puntero nulo.

Tenga en cuenta que desde un argumento tipo de matriz (como char*[]) es en realidad un argumento de tipo puntero en el disfraz, los dos siguientes son dos formas válidas para escribir (2) y ambos significan exactamente lo mismo:

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

Algunas implementaciones pueden permitir otros tipos y números de parámetros; Debería verificar la documentación de su implementación para ver qué es lo que admite.

main() se espera que regrese a cero para indicar el éxito y que no sea cero para indicar la falla. No es necesario que escriba explícitamente una declaración return en main(): si deja que main() devuelva sin una declaración explícita return, es lo mismo que si hubiera escrito return 0;. Los siguientes dos main() funciones tienen el mismo comportamiento:

int main() { } 
int main() { return 0; } 

Hay dos macros, EXIT_SUCCESS y EXIT_FAILURE, definidos en <cstdlib> que también se pueden devolver desde main() para indicar el éxito y el fracaso, respectivamente.

El valor devuelto por main() se pasa a la función exit(), que finaliza el programa.

Tenga en cuenta que todo esto se aplica solo al compilar para un entorno alojado (informalmente, un entorno donde tiene una biblioteca estándar completa y hay un sistema operativo que ejecuta su programa). También es posible compilar un programa C++ para un entorno independiente (por ejemplo, algunos tipos de sistemas integrados), en cuyo caso el inicio y la terminación están completamente definidos por la implementación y es posible que ni siquiera se requiera una función main(). Sin embargo, si está escribiendo C++ para un sistema operativo de escritorio moderno, está compilando para un entorno alojado.

+1

IIRC los únicos valores de devolución garantizados son 0, EXIT_SUCCESS (el mismo efecto que 0) y EXIT_FAILURE.EDITAR: Ah, OK, pueden devolverse otros valores de estado distintos de cero, pero con un significado definido por la implementación. Solo se garantiza que EXIT_FAILURE se interpretará de alguna manera como un valor de falla. –

+0

No estaría de más especificar (solo para estar seguro) que esto es en referencia a C++. Los usuarios de Java/C# pueden estar confundidos ya que esos lenguajes en realidad * requieren * el punto de entrada para -contrariamente- estar en una clase (por alguna razón). Además, ¿no es el antiguo formato 'void main' un holdover de C? – Synetech

+3

@Synetech: la pregunta pregunta en su primera frase, "¿Cuál es la firma correcta de la función principal en C++?" y la pregunta está etiquetada tanto [C++] como [C++ - faq]. No puedo evitarlo si los usuarios de Java o C# (o cualquier otra persona) todavía están confundidos. C# requiere que 'Main' sea una función miembro estática porque ni siquiera tiene funciones que no sean miembros. Incluso C89 requiere 'main' para devolver' int'. No estoy lo suficientemente familiarizado con K & R C para conocer sus reglas exactas, pero supongo que también requiere que 'main' devuelva' int' ya que 'main' sin tipo de retorno era algo común y no type = implicit' int' en K & R . –

3

Las dos líneas principales válidas son int main() e int main (int, char * []) ​​Cualquier otra cosa puede compilarse o no. Si main no devuelve explícitamente, se devuelve implícitamente un valor 0.

+0

Nunca he visto código no compilado cuando menciono que el tipo de retorno de 'main' es nulo. ** ¿Hay alguna razón específica por la que el tipo de devolución de main deba ser int? ** –

+4

La especificación del lenguaje dice main debe tener un tipo de retorno de int. Cualquier otro tipo de devolución permitido por su compilador es una mejora específica del compilador. Básicamente, usar el vacío significa que estás programando en un lenguaje similar pero no en C++. – stonemetal

+2

La razón por la cual el estándar requiere un 'int' como el tipo de retorno de' main' es que este valor se le da al shell como el código de salida del programa, y ​​'sh' espera un' int'. – uckelman

11

a partir de documentos estándar., 3.6.1.2 Función principal,

Será tiene un retorno tipo de tipo int, pero por lo demás su tipo es definido por la implementación. Todas las implementaciones se permiten tanto de los las definiciones siguientes de principal:

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 suministrarán en argv [0] a través de argv [argc-1] como punteros a el init ial caracteres de cadenas multibyte terminadas en nulo .....

Espero que ayude ..

+1

¿hay alguna razón específica de por qué el tipo de devolución de 'main' debe ser' int'? –

+1

@SuhailGupta: Para que el proceso de llamada sepa si este proceso debe considerarse exitoso o no. Permitir 'void' rompe ese modelo. Ni siquiera tiene sentido si lo hiciera significar "siempre considerar el éxito". Debido a que no tenía forma de decir si el proceso realmente falló, ¿de verdad tuvo éxito? No, devuelve 'int'. –

2

detalles sobre los valores de retorno y su significado

por 3.6.1 ([basic.start.main]):

Una declaración de retorno en main tiene el efecto de dejar la función main (destruir cualquier objeto con cambio automático duración de almacenamiento) y llamando al std::exit con el valor de retorno como argumento. Si el control llega al final de main sin encontrar una declaración return, el efecto es el de ejecutar

return 0; 

El comportamiento de std::exit se detalla en la sección 18.5 ([support.start.term]), y describe el código de estado:

Finalmente, el control se devuelve al entorno de host. Si el estado es cero o EXIT_SUCCESS, se devuelve una forma definida por la implementación del estado de finalización exitosa. Si el estado es EXIT_FAILURE, se devuelve una forma de implementación definida de la terminación de estado fallido. De lo contrario, el estado devuelto está definido por la implementación.

3

La formulación exacta de la última norma publicada (C++ 14) es:

Una aplicación deberá permitir tanto

  • función de () regresar int y

  • una función de (int, puntero a puntero a char) volver int

como el tipo de main.

Esto deja claro que ya existen alternativas están permitidos siempre y cuando el tipo de main es el tipo int() o int(int, char**). Así también se permiten las siguientes:

  • int main(void)
  • auto main() -> int
  • int main ( )
  • signed int main()
  • typedef char **a; typedef int b, e; e main(b d, a c)
+1

NB. Publiqué esta respuesta como en los comentarios a otro hilo, alguien intentó citar este hilo como evidencia de que 'int main (void)' no era correcto en C++. –

+3

@Stargateur 'auto main() -> int' no tiene un tipo de retorno deducido. Preste atención a {en "(auto main() {... no está permitido)" y aprenda a saber cuándo aún no sabe lo suficiente como para agregar algo significativo. – hvd

Cuestiones relacionadas