Regla 0x0014h: Auditor de inicialización de arreglos unidimensionales con exceso de elementos
Sintaxis y formato visual (0x00XX)
0x0014h: Auditor de inicialización de arreglos unidimensionales con exceso de elementos¶
Enunciado normativo¶
La lista de inicialización de un arreglo con dimensión explícita NO DEBE contener más elementos que la cantidad declarada. Si se desconoce el tamaño, DEBE omitirse la dimensión y dejar que el compilador la infiera.
¿Por qué existe esta regla?¶
El problema¶
Cuando se declara int v[3] y se inicializa con cuatro valores, se está pidiendo
almacenar un dato en una posición que no existe. El estándar prohíbe esa
situación de forma explícita: es una violación de restricción que el compilador
debe diagnosticar. El error no es silencioso en un compilador conforme, pero un
compilador laxo o una herramienta que no diagnostique podría escribir el cuarto
valor más allá del arreglo, pisando memoria vecina. La forma de evitarlo es
contar bien o, mejor, no fijar la dimensión y dejar que el compilador la derive
de la lista.
Consecuencias de violarla¶
| Tipo de consecuencia | Efecto concreto |
|---|---|
| Compilación | error: excess elements in array initializer con GCC y Clang. |
| Comportamiento indefinido | Si el compilador no diagnosticara, se escribiría fuera de los límites del objeto. |
| Bug silencioso | El exceso puede desplazar datos adyacentes y corromper otra variable. |
| Mantenibilidad | El tamaño real del arreglo y su contenido dejan de coincidir. |
Fundamento en el estándar y en la cátedra¶
ISO/IEC 9899:2011 §6.7.9p2 establece que ningún inicializador puede aportar un valor a un objeto que no esté contenido en la entidad inicializada, y §6.7.9p21 define que los elementos no inicializados de un arreglo se completan con cero. La cátedra adopta la regla como higiene obligatoria de inicialización: el tamaño y la lista deben concordar, o la dimensión debe omitirse. Se relaciona con 0x5001h: Los arreglos estáticos deben ser creados con un tamaño fijo en tiempo de compilación, que prohíbe los arreglos de longitud variable.
Alcance y excepciones¶
Aplica a cualquier arreglo unidimensional con dimensión explícita, sea local,
global o static. No aplica a arreglos multidimensionales, cuyo análisis de
exceso es por subagregado, ni a un arreglo sin dimensión (int v[] = {...}),
donde el tamaño se infiere y nunca puede haber exceso. No hay excepción para
“probar” tamaños: si hay duda, se omite la dimensión.
Ejemplos exhaustivos¶
❌ Contraejemplo 1 — Exceso entero¶
int arr[3] = {1, 2, 3, 4};Por qué falla: la declaración reserva tres posiciones (0, 1, 2) y la lista
intenta escribir una cuarta. GCC aborta la compilación con excess elements in array initializer; no hay forma de que el programa se ejecute.
❌ Contraejemplo 2 — Cadena más larga que el arreglo¶
char nombre[5] = "abcdef";Por qué falla: "abcdef" ocupa siete bytes contando el terminador nulo, y el
arreglo sólo reserva cinco. El compilador reporta que la cadena es demasiado
larga para el arreglo; el terminador nulo queda fuera.
✅ Ejemplo conforme 1 — Tamaño y lista coherentes¶
int arr[3] = {1, 2, 3};Por qué cumple: tres elementos para tres posiciones; no hay exceso ni ambigüedad sobre el tamaño.
✅ Ejemplo conforme 2 — Dimensión inferida y arreglo parcial¶
int valores[] = {10, 20, 30, 40};
int parciales[5] = {1, 2};Por qué cumple: en el primer caso el compilador infiere cuatro posiciones; en el segundo los tres elementos restantes se completan con cero conforme a §6.7.9p21, comportamiento idiomático compatible con 0x3018h: Inicialización idiomática de agregados con {0} en lugar de memset inmediato.
⚠️ Casos límite¶
Cadena con tamaño exacto sin terminador:
char s[3] = "abc";es legal porque descarta el'\0'; es sutil y suele ser un bug si luego se usa como cadena.Llave vacía
{}: no es C11 estándar (hasta C23 no se admite sin elementos); usar{0}.Coma final:
{1, 2, 3,}es legal y no agrega un elemento.Multidimensionales:
int m[2][2] = {{1, 2}, {3, 4}};cuenta por subarreglo, no por total.Arreglo
const: mismas reglas; ver 0x301Ch: Detector de variables locales no inicializadas con modificador const.
Cómo detectarla¶
| Herramienta | Comando | Señal |
|---|---|---|
gaff | gaff check archivo.c | Reporta listas de inicialización con más elementos que la dimensión. |
gcc / clang | gcc -Wall -Wextra -std=c11 -c archivo.c | error: excess elements in array initializer. |
| Revisión manual | — | Contar elementos de la lista contra la dimensión declarada. |
Checklist de autocontrol¶
La cantidad de elementos coincide con la dimensión declarada.
Si no necesito recordar el tamaño, omití la dimensión para que se infiera.
Sé que los elementos faltantes se completan con cero (§6.7.9p21).
No dejé una cadena sin lugar para su terminador nulo.
Los arreglos tienen tamaño fijo, sin VLA (0x5001h: Los arreglos estáticos deben ser creados con un tamaño fijo en tiempo de compilación).
Reglas relacionadas¶
0x5001h: Los arreglos estáticos deben ser creados con un tamaño fijo en tiempo de compilación — arreglos con tamaño fijo en tiempo de compilación.
0x300Ch: Verificá siempre los límites de los arreglos antes de acceder a sus elementos — validar índices antes de acceder.
0x3018h: Inicialización idiomática de agregados con {0} en lugar de memset inmediato — inicialización de agregados con
{0}.0x0010h: Prohibición de llaves redundantes en inicialización de tipos escalares — no usar llaves en inicialización de escalares.
0x010Fh: Prohibición de constantes numéricas mágicas en índices de arreglos — evitar índices literales mágicos.