Regla 0x200Eh: Uso obligatorio de 'void' explícito en funciones sin parámetros
Funciones, contratos y modularizacion (0x20XX)
0x200Eh: Uso obligatorio de ‘void’ explícito en funciones sin parámetros¶
Enunciado normativo¶
DEBE escribirse
(void)en la lista de parámetros de toda función que no recibe argumentos. NO DEBE dejarse la lista vacía()en una declaración o definición de función.
¿Por qué existe esta regla?¶
El problema¶
En C, int f() y int f(void) no significan lo mismo. Una lista vacía en una
declaración indica que la función toma un número indeterminado de
parámetros, herencia de la era K&R. El compilador deja de verificar los
argumentos: una llamada con parámetros de más o de menos puede compilar y
producir un desastre en tiempo de ejecución. En cambio, (void) declara
explícitamente que la función no toma ninguno, y el compilador exige que las
llamadas lo respeten.
La diferencia se nota con -Wstrict-prototypes: toda función con () dispara
la advertencia. Escribir (void) cuesta seis caracteres y elimina una clase
entera de errores de invocación.
Consecuencias de violarla¶
| Tipo de consecuencia | Efecto concreto |
|---|---|
| Falta de verificación | Una llamada con argumentos de más compila sin error. |
| Portabilidad | El comportamiento frente a prototipos K&R cambia entre compiladores. |
| Warning | -Wstrict-prototypes marca cada declaración vacía. |
Fundamento en el estándar y en la cátedra¶
C11 §6.7.6.3 párrafo 14 define que la lista (void) especifica que la función
no tiene parámetros. Además, el estándar marca como obsolescente la
declaración con lista vacía (§6.11.6). La cátedra la prohíbe para que el
contrato de la función coincida con su firma verificada, reforzando
0x2003h: Todas las funciones deben incluir documentación completa y estructurada. Es una regla con corrección automática porque la
transformación es puramente sintáctica.
Alcance y excepciones¶
Aplica a declaraciones, definiciones, typedef de punteros a función y
prototipos. No se aplica a funciones que sí reciben parámetros, aunque
reciban una cantidad variable (printf(const char *formato, ...)).
Excepción: las funciones de la biblioteca estándar con firma K&R
obsolescente (int rand()), cuyos encabezados no controlás, se usan como están
pero no se copian como modelo.
Ejemplos exhaustivos¶
❌ Contraejemplo 1 — Prototipo con lista vacía¶
int obtener_contador();
int main(void)
{
return obtener_contador(42);
}Por qué falla: obtener_contador() admite argumentos, así que la llamada con
42 compila. La función los ignora por casualidad, pero el error pasa
inadvertido; con (void) el compilador habría rechazado la llamada.
❌ Contraejemplo 2 — Definición con lista vacía¶
void reiniciar()
{
tabla_limpiar();
}Por qué falla: aunque no recibe nada, la definición con () no declara un
prototipo completo. El compilador no puede verificar la consistencia con otras
declaraciones y -Wstrict-prototypes advierte.
✅ Ejemplo conforme 1 — Prototipo y definición con void¶
int obtener_contador(void);
int main(void)
{
return obtener_contador();
}
int obtener_contador(void)
{
return CONTADOR_INICIAL;
}La firma coincide en el prototipo y en la definición, y el compilador verifica que no se pasen argumentos.
✅ Ejemplo conforme 2 — Puntero a función sin parámetros¶
typedef int (*callback_t)(void);
static int inicial(void)
{
return OK;
}
int main(void)
{
callback_t cb = inicial;
return cb();
}El typedef usa (void) para declarar que el callback no recibe parámetros;
de otro modo, int (*)( ) tendría una firma indeterminada e incompatible.
⚠️ Casos límite¶
main: debe serint main(void)oint main(int argc, char *argv[]); nuncaint main().Funciones variádicas: requieren al menos un parámetro nombrado;
(void)no aplica.
Cómo detectarla¶
| Herramienta | Comando | Señal |
|---|---|---|
gaff | gaff check archivo.c | Firma con paréntesis vacío. |
gaff | gaff fix archivo.c | Inserta void en la lista vacía. |
gcc / clang | gcc -Wall -Wextra -Wstrict-prototypes -std=c11 ... | “function declaration isn’t a prototype”. |
Checklist de autocontrol¶
¿Toda función sin parámetros usa
(void)?¿Lo mismo en prototipos, definiciones y
typedefde callbacks?¿
mainestá declarado convoido conargc/argv?¿Compilo con
-Wstrict-prototypesy no hay advertencias?
Reglas relacionadas¶
0x2012h: Tipo de retorno obligatorio ‘int’ en la función main() —
maindebe declararseinty con(void)si no recibe argumentos.0x0012h: Validador de formato canónico en firmas de punteros a función — formato canónico de punteros a función, donde
(void)también aplica.