¿Por qué no usamos (void) en main?

La gente usa void main() /*empty parens ()*/

Me han enseñado a escribir void main(void)

¿Alguna idea de cuál es la diferencia?

No estoy seguro de cuáles son los estándares hoy en día, pero en el C ANSI tradicional, el uso de paréntesis vacíos indica que la función puede tomar cualquier número de argumentos. Por otro lado, declarar un parámetro void indica que la función solo toma cero argumentos . En este caso (y muchos otros), realmente no importa demasiado.

Sin embargo, si quieres ser estricto, probablemente es mejor definir el parámetro void . Por supuesto, la función main también se puede definir como int main(int argc, const char* argv[]) , que es perfectamente válida, pero a menudo innecesaria si no le importan los argumentos.

De la norma C99:

5.1.2.2.1 Inicio del progtwig

La función llamada al inicio del progtwig se llama main. La implementación no declara ningún prototipo para esta función. Se definirá 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 se puede usar cualquier nombre, 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.

Cuando main se define sin parámetros, ¿seguirán presente argc y argv en la stack?

Estos prototipos de main () son ambos no estándar.

La precisión en esa pregunta se puede encontrar en comp.lang.c faq: http://c-faq.com/decl/main.html

EDITAR : se cambió “incorrecto” a “no estándar” ya que la norma permite prototipos definidos por la implementación.

No hay diferencia pero usualmente main debe devolver int. Algunos comstackdores le darán una advertencia (al menos el comstackdor GNU – gcc):

 $ cat xc void main(void){} $ gcc xc xc: In function `main': xc:1: warning: return type of 'main' is not `int' 

Como se mencionó el prototipo de main es (según norma):

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

main es una función, como otra función. Casi. De todos modos, al ser una función, es llamada por algún otro código (un código de inicio). Generalmente (leer: casi siempre) int main() es la correcta, pero de hecho, la correcta depende de la plataforma en la que la estés trabajando. Ya que, como se dijo, la función principal podría ser llamada por un código de inicio que no pasa ningún argumento, y que no espera un valor de retorno en un registro específico (de modo que el void main(void) sea ​​correcto).

El int main() es correcto ya que normalmente el código de inicio espera un valor de retorno y pasa dos argumentos. Al decir int main(void) usted dice que main no toma ningún argumento, eso es falso en la mayoría de los casos. Con () dices que hay argumentos (uno, dos, tres, no te importa), pero no estás interesado en ellos, por lo que no estás interesado en decir qué son y qué tipo son.

Como puedo ver en los códigos, el prototipo más utilizado para entornos “normales” (sin dispositivos incrustados u otros entornos “extraños” a los que se puede llamar main de manera diferente) es int main() cuando ignora el int argc, char **argv pasado. argumentos (GCC se queja porque estamos usando una versión para gcc adecuada para el medio ambiente; pruébela con una versión de GCC cruzada para uno de los entornos donde el código de inicio no pasa ningún argumento y no espera un valor de retorno)

editar

Sólo para ser amable con las personas escépticas; en el entorno donde se llama la función principal, con dos argumentos, los siguientes

 int func() { return 0; } int func2(void) { return 1; } int main(void) { int a; a = func(a, a); /* A */ a = func2(a); /* B */ return 0; } 

no dice ningún error para A, mientras que para B dice too many arguments to function 'func2' , comstackdo con gcc -std=c99 -pedantic . Cambiar int main(void) en int main() no hace ninguna diferencia, y no hay advertencias.

En otros entornos (no puedo hacer pruebas prácticas ahora), void main(void) está bien, mientras que en este caso genera una advertencia. La advertencia no se debe solo al estándar, sino solo porque en el entorno en uso, el prototipo principal no coincide. El estándar parece permitir cualquier otra “configuración” para main.

En el caso de OP, considerando el entorno “normal” (OS como GNU / Linux, por ejemplo), donde se pasan dos argumentos al principal, y se espera un valor de retorno, es preferible el int main() (los argumentos se insertan en la stack) por el código de inicio, diga int main(void) o no, por lo que int main() tiene más sentido para mí

editar

Una nota más, siempre para persona escéptica. Como ya se demostró, B genera un error, ya que he dicho que es int func2(void) pero lo llamo pasar un argumento. Entonces, supongamos que podemos comstackr el código de inicio y vincularlo, como cualquier otro código. En algún lugar, llamará al principal, de una manera como

 retval = main(argc, argv); 

Si usamos int main(void) , el comstackdor se detendrá y dará un error, ya que el código de inicio (en este entorno) está intentando llamar main con dos argumentos. Si usamos int main() no pasa nada y el código se comstack correctamente.

Entonces, int main() es superior a int main(void) (en un entorno donde esperamos que dos argumentos sean posibles)

editar

Más probable es que la llamada sea como

 retval = main(_argc, _argv, environ); 

En muchos sistemas, pero esto no cambia el discurso anterior.

edición final

¿Alguien encontró que cuando se construye una herramienta de línea de comandos (es decir, en sistemas donde int argc, char ** tiene sentido) con int main(void) , el comstackdor / vinculador elegido vincula un código de inicio donde se llama al main sin argumentos (sea cual sea el las convenciones de llamada son), y en su lugar, al construir con int main(int argc, char **argv) el código de inicio es diferente y, de hecho, llama a main con esos dos argumentos (incluso si el main sí no los usa).