¿Es legal recurrir a main () en C++? [duplicar]


Esta pregunta ya tiene una respuesta aquí:

He leído que el estándar C++ prohíbe la recursividad en main(), pero g++ compila el siguiente código sin quejarse:

int main()
{
    main();
}

¿alguien Puede aclarar esto?

Author: Andreas Bonini, 2010-12-23

5 answers

De acuerdo con el estándar en 3.6.1/3, no es :

La función main no se utilizará (3.2) dentro de un programa

La definición de utilizada es:

Un objeto o no sobrecargado la función se usa si su nombre aparece en una expresión potencialmente evaluada.

 50
Author: icecrime,
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
2010-12-23 13:20:13

Voy a hacer el pescado y explicar por qué esto es verboten. Antes de que un programa C o C++ pueda comenzar a ejecutarse, el CRT debe inicializarse primero. Abre stdin / out / err, llama a inicializadores, ese tipo de cosas. Hay dos estrategias básicas para hacer esto, un detalle de implementación de plataforma pesada.

  • La dirección de inicio del programa apunta a la función CRT init, que eventualmente llama a main (). Común en los sistemas operativos con todas las funciones que tienen un cargador de lujo que puede admite secciones arbitrarias en la imagen ejecutable.

  • El compilador inyecta código en la función main () que llama a la función de inicialización CRT. La función start es siempre main (). Común en plataformas integradas con capacidades de cargador limitadas. La recursividad de main () es ahora un problema, el código de inicio de CRT será llamado de nuevo con un estado de pila impredecible.

 37
Author: Hans Passant,
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
2011-01-04 14:31:27

La afirmación aquí es que de hecho está específicamente prohibido:

Bueno, los estados estándar:

3.6.1.3
"La función main no se utilizará dentro de un programa."

5.2.2.9
"Se permiten llamadas recursivas, excepto a la función llamada main"

Puedes, por supuesto, hacer esto:

int main(int argc, char* argv[]) {
    return foo(argc, argv);
}
int foo(int argc, char* argv[]) {
    if (some_condition) {
        return foo(argc, argv);
    }
    return 0;
}

(Nota He añadido una cláusula get-out. Ni siquiera puedo hipotéticamente codificar recursión infinita, repite en mí.)

 22
Author: T.J. Crowder,
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
2010-12-23 12:13:39

No es legal. Debe decir 3.6.1-3:

No se utilizará la función main (3.2) dentro de un programa. Vinculación (3.5) de is principales implementación-definida. Un programa que declara main como inline o estático está mal formado. El nombre principal no es de lo contrario reservado. [Ejemplo: miembro funciones, clases y enumeraciones puede ser llamado principal, como pueden las entidades en otros espacios de nombres. ]

 9
Author: BЈовић,
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
2010-12-23 12:14:16

Otras personas han abordado la parte de los estándares. Sin embargo, me gustaría señalar que g++ (al menos 4.6.2) rechazará esto si usa -pedantic-errors con al menos uno de estos errores (dependiendo de la firma main):

error: ISO C++ forbids calling ‘::main’ from within program [-pedantic]
error: ISO C++ forbids taking address of function ‘::main’ [-pedantic]
 1
Author: Matthew Flaschen,
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-03-04 12:36:35