Regla 0x5005h: Organizá la estructura de tus archivos .c de forma estándar
Compilacion, preprocesador y seguridad (0x50XX)
0x5005h: Organizá la estructura de tus archivos .c de forma estándar¶
Enunciado normativo¶
DEBE ordenarse cada archivo
.cen secciones progresivas: (1) cabeceras estándar, (2) cabeceras de terceros, (3) cabeceras del proyecto, (4) macros y constantes, (5) tipos, (6) prototipos de funciones privadas, (7)mainsi aplica, (8) funciones públicas y (9) funciones privadasstatic.
¿Por qué existe esta regla?¶
El problema¶
Un archivo de C no impone un orden más allá de que las declaraciones precedan a
su uso. Cuando cada archivo elige uno distinto (defines en el medio, prototipos
después de main, #include al final), el lector no puede anticipar dónde está
cada cosa. El orden canónico vuelve al archivo predecible y los prototipos
static agrupados liberan el orden de implementación.
Consecuencias de violarla¶
| Tipo de consecuencia | Efecto concreto |
|---|---|
| Compilación | Uso sin prototipo previo: implicit declaration, error con -Werror. |
| Mantenibilidad | Cada archivo exige una lectura completa para saber qué expone. |
| Maquetado | main escondido en el medio dificulta localizar el flujo principal. |
Fundamento en el estándar y en la cátedra¶
ISO/IEC 9899:2011 §6.9 regula las definiciones externas y §6.2.1 los ámbitos: una función debe declararse antes de invocarse. La cátedra fija el orden por convención para que docente y corrector encuentren siempre lo mismo.## Alcance y excepciones
Aplica a todos los .c; los .h se rigen por 0x5003h: Utilizá guardas de inclusión en todos los archivos de cabecera. Excepción: un
ejercicio de una sola función trivial se reduce a includes y main.
Ejemplos exhaustivos¶
❌ Contraejemplo 1 — Prototipo posterior al uso¶
int main(void)
{
return duplicar(21);
}
int duplicar(int x)
{
return x * 2;
}Por qué falla: main invoca duplicar sin declaración previa; C11 ya no admite
declaraciones implícitas y -Werror detiene la compilación.
❌ Contraejemplo 2 — Definiciones dispersas y cabecera al final¶
#define ESCALA 2
int calcular(int x)
{
return x * ESCALA;
}
#include <stdio.h>Por qué falla: la cabecera se incluye después de su uso, el #define quedó
arriba y el archivo no tiene secciones reconocibles.
✅ Ejemplo conforme 1 — Esqueleto canónico¶
#include <stdio.h>
#include "calculo.h"
#define ESCALA 2
static int normalizar(int x);
int main(void)
{
return normalizar(21);
}
static int normalizar(int x)
{
return calculo_duplicar(x) / ESCALA;
}Las dependencias quedan arriba, main antes del cuerpo y las funciones privadas
al final; el orden hace evidente qué expone el módulo.
✅ Ejemplo conforme 2 — Módulo sin main¶
#include "punto.h"
static int abs_entero(int x);
int punto_distancia(punto_t a, punto_t b)
{
return abs_entero(a.x - b.x) + abs_entero(a.y - b.y);
}
static int abs_entero(int x)
{
if (x < 0) {
return -x;
}
return x;
}En un TAD la sección 7 se omite; la sección 6 permite que punto_distancia use
abs_entero sin importar la posición física.
⚠️ Casos límite¶
Un solo archivo con todo: igual separá includes, tipos y funciones.
Prototipos
static: opcionales si definís en orden, pero recomendables.Includes condicionales: van en la sección de includes, nunca dentro de una función.
mainno aplica en un módulo de biblioteca.
Cómo detectarla¶
| Herramienta | Comando | Señal |
|---|---|---|
gaff | gaff check archivo.c | Marca 0x5005h con #include o #define fuera de su sección. |
gcc / clang | gcc -std=c11 -Wall -Wextra -Werror -pedantic archivo.c | implicit declaration of function. |
Checklist de autocontrol¶
¿Las cabeceras estándar van antes que las del proyecto?
¿Los
#defineytypedefestán agrupados antes de las funciones?¿Los prototipos
staticpreceden a las implementaciones?¿
mainestá antes del cuerpo de las demás funciones?¿Evité
#includey#definedentro de funciones?
Reglas relacionadas¶
0x0205h: En archivos .c la inclusión de la cabecera propia debe figurar en primer lugar — la propia cabecera primero valida que sea autosuficiente.
0x5007h: Inclusiones redundantes o duplicadas de la misma cabecera #include — duplicar cabeceras rompe el orden y la limpieza.