Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Regla 0x010Fh: Prohibición de constantes numéricas mágicas en índices de arreglos

Nomenclatura e identificadores (0x01XX)

Universidad Nacional de Río Negro

0x010Fh: Prohibición de constantes numéricas mágicas en índices de arreglos

Enunciado normativo

NO DEBE accederse a posiciones fijas de un arreglo con literales mayores que 2 (vec[7]). Esos índices DEBEN expresarse con constantes simbólicas (#define o enum) que nombren su significado de dominio. Los índices 0, 1 y 2, y las variables de iteración, quedan exceptuados por su uso idiomático.

¿Por qué existe esta regla?

El problema

Un literal como registro[7] no dice qué hay en la posición 7 ni por qué se la elige. Toda la semántica del programa —que la columna 7 es el total, que el campo 3 es el legajo— queda grabada en un número que el lector debe descifrar. Peor: si la estructura cambia de tamaño o de orden, los índices literales quedan desalineados sin que nada avise, y un acceso fuera de límites es comportamiento indefinido. Un nombre simbólico convierte el número en documentación y en un único punto de cambio.

Consecuencias de violarla

Tipo de consecuenciaEfecto concreto
Bug silenciosoReordenar los campos invalida todos los índices literales sin error de compilación.
Comportamiento indefinidoSi el literal excede la dimensión —por ejemplo tras reducir el arreglo—, el acceso es fuera de límites.
LegibilidadEl lector debe inferir el significado de cada posición.
MantenibilidadCambiar una posición obliga a buscar el literal en todo el archivo.

Fundamento en el estándar y en la cátedra

ISO/IEC 9899:2011 §6.5.2.1 define la indexación de arreglos y §6.4.4 los literales enteros; el estándar no prohíbe los números, pero el acceso fuera de límites es comportamiento indefinido. La cátedra exige símbolos con significado de dominio porque el índice es, en la mayoría de los ejercicios, un campo de un registro o una columna de una matriz. Se articula con 0x300Dh: Utilizá enum en lugar de ‘números mágicos’ para conjuntos de estados y valores constantes, que recomienda enum para conjuntos de estados, y con 0x300Ch: Verificá siempre los límites de los arreglos antes de acceder a sus elementos, que exige validar los límites.

Alcance y excepciones

Aplica a accesos con índice literal mayor que 2. No aplica a los índices 0, 1 y 2, reservados para operaciones como intercambiar dos elementos o leer el primero, ni a variables de iteración (v[i]), que no son mágicas. No alcanza a las dimensiones de declaración (int m[3][3]), que describen el tipo y no un acceso, aunque a partir de 3 conviene igualmente una constante.

Ejemplos exhaustivos

❌ Contraejemplo 1 — Índice literal sin significado

registro[7] = 100;

Por qué falla: no se sabe qué es la posición 7. Si el arreglo tiene menos de ocho elementos, además es un acceso fuera de límites. El número no documenta el campo ni se actualiza si la estructura cambia.

❌ Contraejemplo 2 — Índices literales en una comparación

if (fila[3] > fila[2]) {
    intercambiar(&fila[3], &fila[2]);
}

Por qué falla: 3 y 2 aquí representan campos distintos, pero nada lo dice; el lector no puede distinguir un campo de un desplazamiento casual. fila[2] queda exceptuado por la regla, pero mezclar 2 y 3 en la misma expresión vuelve necesario nombrar ambos.

✅ Ejemplo conforme 1 — Constante simbólica con significado

#define INDICE_TOTAL 7

int registro[8];

registro[INDICE_TOTAL] = 100;

Por qué cumple: INDICE_TOTAL declara qué mide esa posición y el arreglo tiene espacio suficiente; el valor está dentro de los límites. El nombre es el único lugar donde cambiar el desplazamiento.

✅ Ejemplo conforme 2 — Enumeración de campos e iteración

enum {
    COL_NOMBRE = 0,
    COL_EDAD = 1,
    COL_LEGAJO = 2
};

int fila[3];

fila[COL_LEGAJO] = 12345;

for (size_t i = 0; i < 3; i++) {
    printf("%d\n", fila[i]);
}

Por qué cumple: cada campo tiene nombre (enum conforme a 0x300Dh: Utilizá enum en lugar de ‘números mágicos’ para conjuntos de estados y valores constantes), el acceso es legible y la iteración usa una variable, no un literal. fila[0] y fila[1] podrían exceptuarse, pero nombrarlos hace el código más claro.

⚠️ Casos límite

Cómo detectarla

HerramientaComandoSeñal
gaffgaff check archivo.cReporta accesos arreglo[N] con N > 2 literal.
gcc / clanggcc -Wall -Wextra -std=c11 -c archivo.cNo reporta el número mágico, pero sí un acceso fuera de límites detectable.
Revisión manualBuscar corchetes con literales mayores que 2.

Checklist de autocontrol

Reglas relacionadas