El C 99 Standard (5.1.2.2.1 Programa de inicio) dice que una implementación impone ninguna prototipo de la función main(), y que un programa puede definirlo como cualquiera de:
1) int main (vacío);
2) int main (int argc, char * argv []);
o de una manera semánticamente equivalente a 2), p.
2 ') int main (int argc, char ** argv);
o en otras formas de implementación definidas. Hace no mandato que el prototipo:
3) int main (int argc, char * argv [], char * envp []);
tendrá el comportamiento previsto, aunque ese prototipo debe compilarse, porque debe compilarse cualquier prototipo. 3) es compatible con GCC y Microsoft C, entre otros compiladores. (N.B. El tercer prototipo del cuestionario tiene char * envp en lugar de char * envp [], ya sea por accidente o porque tiene algún otro compilador).
Tanto GCC como Microsoft C compilarán main() con cualquier prototipo en absoluto, como deberían. Analizan el prototipo que realmente especifica y genera el lenguaje ensamblador para consumir los argumentos, si los hay, de la manera correcta. Así, por ejemplo, van a generar cada una el comportamiento esperado para el programa:
#include <stdio.h>
void main(double d, char c)
{
printf("%lf\n",d);
putchar(c);
}
si se pudiera encontrar una manera de pasar un doble y un char directamente al programa, no a través de una matriz de cadenas.
Estas observaciones se pueden verificar habilitando los listados de lenguaje ensamblador para programas experimentales.
La cuestión de cómo el CRT estándar del compilador nos permite invocar la implementación generada de main() es distinta de la cuestión de cómo se puede definir main() para el compilador.
Tanto para GCC como para MS C, main() puede definirse de la manera que deseemos. En cada caso, sin embargo, el CRT estándar de la implementación, AFIK, admite pasar argumentos a main() solo que según 3). Entonces 1) - 2 ') también tendrá el comportamiento esperado al ignorar los argumentos en exceso, y no tenemos otras opciones para proporcionar un tiempo de ejecución no estándar propio.
La respuesta de Hans Passant parece incidentalmente engañosa al sugerir que argc le dice a la función cuántos argumentos subsiguientes consumir de la misma manera que el primer argumento para printf(). Si argc está presente, solo denota el número de elementos en la matriz pasada como el segundo argumento argv. No indica cuántos argumentos se pasan a main(). Tanto GCC como MS C averiguan cómo se esperan los argumentos al analizar el prototipo que usted escribe, básicamente lo que hace un compilador con cualquier función , excepto, como printf(), que están definidos para tomar una cantidad variable de argumentos.
main() no toma una cantidad variable de argumentos.Toma los argumentos que especifique en su definición, y los CRT estándar de los compiladores habituales asumen que son (int, char * [], char * []).
Probablemente sean tiempos de ejecución de Windows C precisos de 32 bits. Pero, ¿qué pasa en otras plataformas donde difiere ABI? Por ejemplo, x64 donde los parámetros se pasan en los registros incluso para cdecl. ¿Y qué tal una función 'main' conforme declarada así' int main (double d) '? ¿Y dónde en el estándar dice que todas las funciones 'main' deben usar' __cdecl' que ni siquiera forma parte del estándar? ¿Y qué hay de 'WinMain'? –
Bueno, al menos la primera frase de su respuesta ahora es precisa. ;-) –
Sour grapes David? Su respuesta puede ser correcta, simplemente no conozco ningún compilador que soporte el tipo de reflexión que se requeriría para que funcione. Solo puedo ofrecer lo que he visto usado en 8 de ellos que estudié lo suficiente, todos usaron una convención de llamadas de cdecl. Probablemente porque es muy fácil de implementar, aunque no es tan fácil generar el código. La reflexión es una característica muy poco común en C. ¿Quizás puedas hacerlo más convincente dando un ejemplo de dicho compilador? –