Regla 0x2012h: Tipo de retorno obligatorio 'int' en la función main()
Funciones, contratos y modularizacion (0x20XX)
0x2012h: Tipo de retorno obligatorio ‘int’ en la función main()¶
Enunciado normativo¶
DEBE declararse
maincon tipo de retornoint. NO DEBE usarsevoid main,main()sin tipo ni ninguna variante no estándar. El retorno DEBE informar el estado de terminación del programa.
¿Por qué existe esta regla?¶
El problema¶
main no es una función cualquiera: es el punto de entrada cuyo retorno se
convierte en el código de salida del proceso. void main miente sobre ese
canal: el sistema operativo y las herramientas que encadenan programas (make,
scripts, el runner de la cátedra) esperan un entero. Además compila en algunos
compiladores viejos por permisividad, lo que da falsa sensación de validez,
pero GCC moderno advierte y otros entornos no lo aceptan.
Consecuencias de violarla¶
| Tipo de consecuencia | Efecto concreto |
|---|---|
| No portabilidad | void main es inválido fuera del dialecto que lo toleraba. |
| Integración | El código de salida del proceso queda indeterminado para scripts. |
| Contrato | La función de entrada no cumple el modelo arranque/terminación. |
Fundamento en el estándar y en la cátedra¶
C11 §5.1.2.2.1 define las formas válidas de main: int main(void) e
int main(int argc, char *argv[]). El retorno es int, y si el control llega
al final sin return, el estándar garantiza un 0 implícito (§5.1.2.2.3). La
cátedra exige la forma estándar para evaluar automáticamente; el runner usa el
código de salida para distinguir éxito de fallo (0x2007h: Los valores de retorno numéricos deben definirse como constantes de preprocesador o enums).
Alcance y excepciones¶
Aplica solo a main. Las demás funciones pueden devolver void, tipos
escalares, punteros o estructuras, según su contrato. No se admiten variantes
como int32_t main, long main ni static int main.
Excepción: implementaciones freestanding pueden definir su propio punto de
entrada, pero el marco de la materia usa siempre un entorno hosted con
int main.
Ejemplos exhaustivos¶
❌ Contraejemplo 1 — void main¶
#include <stdio.h>
void main(void)
{
printf("Hola, mundo\n");
}Por qué falla: declarar void en main es inválido según C11. El compilador
puede aceptarlo con advertencia, pero el programa no informa su estado de
terminación y no es portable.
❌ Contraejemplo 2 — main sin tipo de retorno¶
#include <stdio.h>
main()
{
printf("Hola\n");
}Por qué falla: en C moderno, omitir el tipo de retorno ya no implica int
(el estilo implícito fue eliminado). Además, () deja la lista de parámetros
indeterminada, en contra de 0x200Eh: Uso obligatorio de ‘void’ explícito en funciones sin parámetros.
✅ Ejemplo conforme 1 — Forma canónica sin argumentos¶
#include <stdio.h>
int main(void)
{
printf("Hola, mundo\n");
return 0;
}int main(void) es la forma estándar para programas que no leen argumentos. El
retorno 0 señala éxito y coincide con EXIT_SUCCESS de <stdlib.h>.
✅ Ejemplo conforme 2 — Entrada con argumentos y código de error¶
#include <stdio.h>
int main(int argc, char *argv[])
{
if (argc != 2) {
fprintf(stderr, "Uso: %s <archivo>\n", argv[0]);
return ERROR_ARGUMENTOS;
}
FILE *f = fopen(argv[1], "r");
if (f == NULL) {
perror("fopen");
return ERROR_APERTURA;
}
fclose(f);
return 0;
}El uso de argc/argv sigue la firma exacta del estándar y los códigos de
error con nombre respetan 0x2007h: Los valores de retorno numéricos deben definirse como constantes de preprocesador o enums.
⚠️ Casos límite¶
returnimplícito: omitir elreturnfinal es válido, pero la cátedra prefiere escribirlo para que el valor sea explícito.exit():exit(EXIT_FAILURE)también termina el programa; no exime de declararint main.
Cómo detectarla¶
| Herramienta | Comando | Señal |
|---|---|---|
gaff | gaff check archivo.c | main sin int o con void. |
gaff | gaff fix archivo.c | Reescribe la firma a int main(void). |
gcc / clang | gcc -Wall -Wextra -std=c11 ... | “return type of ‘main’ is not ‘int’”. |
Checklist de autocontrol¶
¿
maindevuelveint?¿Usé
voidoargc/argven su lista de parámetros?¿El retorno distingue éxito de error?
¿Definí los códigos de error con nombre simbólico?
Reglas relacionadas¶
0x200Eh: Uso obligatorio de ‘void’ explícito en funciones sin parámetros —
voidexplícito en funciones sin parámetros,mainincluida.0x2007h: Los valores de retorno numéricos deben definirse como constantes de preprocesador o enums — los códigos de retorno se expresan con símbolos.
0x2008h: Los ejercicios deben ser resueltos mediante funciones —
mainorquesta; la lógica vive en otras funciones.0x4002h: Validá los retornos de las operaciones de lectura y escritura de archivos — si
mainusa E/S, debe verificar sus retornos.