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 0x3010h: Las variables que representan tamaños o índices de arreglos deben ser de tipo size_t

Memoria, punteros y tipos (0x30XX)

Universidad Nacional de Río Negro

0x3010h: Las variables que representan tamaños o índices de arreglos deben ser de tipo size_t

Enunciado normativo

Toda variable que represente una cantidad de bytes, una cantidad de elementos o un índice de arreglo DEBE declararse como size_t, y NO DEBE declararse como int. La variable de iteración del recorrido también DEBE ser size_t cuando se compara contra una cantidad.

¿Por qué existe esta regla?

El problema

size_t es el tipo entero sin signo que el estándar usa para representar tamaños: es el tipo del resultado de sizeof y de strlen, y el que esperan malloc, memcpy y las funciones de arreglos. Es lo suficientemente ancho para contener el tamaño máximo de cualquier objeto en memoria.

Usar int para un tamaño introduce dos problemas: puede no ser lo bastante grande (un arreglo grande desborda) y tiene signo. Al comparar un int con un size_t, el int se convierte a sin signo; un valor negativo se transforma en un número enorme y la comparación i < cantidad se vuelve siempre verdadera. Ese es el origen de los desbordamientos por índice negativo.

Consecuencias de violarla

Tipo de consecuenciaEfecto concreto
Bug lógicoUn índice -1 convertido a size_t es mayor que cualquier cantidad.
DesbordamientoUn int no puede indexar arreglos de más de INT_MAX elementos.
Portabilidadint y size_t cambian de ancho entre plataformas.
MantenibilidadConversiones de signo dispersas y advertencias de compilador.

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

C11 §7.19 define size_t en <stddef.h> como el tipo sin signo del resultado de sizeof. La cátedra lo exige para toda magnitud de memoria, y lo combina con 0x300Ch: Verificá siempre los límites de los arreglos antes de acceder a sus elementos, que prohíbe acceder a un arreglo sin validar el índice. Juntas garantizan comparaciones correctas y sin conversiones de signo.

Alcance y excepciones

Aplica a tamaños, índices, cantidades de elementos, resultados de strlen y sizeof, y variables de iteración de arreglos. No aplica a cantidades que pueden ser negativas por contrato, como diferencias o centinelas; para ellas elegí un tipo con signo explícito y documentá el rango. La impresión de size_t usa el especificador %zu.

Ejemplos exhaustivos

❌ Contraejemplo 1 — Longitud guardada en int

int longitud = strlen(cadena);
for (int i = 0; i < longitud; i++)
{
    procesar(cadena[i]);
}

Por qué falla: strlen devuelve size_t y la asignación lo convierte a int, lo que puede truncar una cadena muy larga. Si longitud fuera negativa por cualquier error de cálculo, el lazo no iteraría nunca. El tipo correcto es size_t.

❌ Contrajemplo 2 — Comparación de int negativo contra size_t

int indice = obtener_indice();
size_t cantidad = contar_elementos();
if (indice < cantidad)
{
    acceder(indice);
}

Por qué falla: si obtener_indice devuelve -1, la conversión a size_t lo transforma en SIZE_MAX y la condición -1 < cantidad es falsa o verdadera según la conversión, pero nunca detecta el error. Hay que validar indice >= 0 antes de comparar contra un tipo sin signo.

✅ Ejemplo conforme 1 — size_t de punta a punta

size_t longitud = strlen(cadena);
for (size_t i = 0; i < longitud; i++)
{
    procesar(cadena[i]);
}

El tipo de la longitud coincide con el de strlen y el índice con el de la comparación. No hay conversiones implícitas de signo y el lazo es correcto para cualquier tamaño que size_t pueda representar.

✅ Ejemplo conforme 2 — Índice con signo validado antes de convertir

int posicion = buscar_posicion(clave);
if (posicion >= 0 && (size_t)posicion < cantidad)
{
    acceder((size_t)posicion);
}

Cuando el valor proviene de una función que puede devolver -1, se valida el signo antes de la conversión a size_t. Recién entonces la comparación es segura. Este patrón se complementa con 0x300Ch: Verificá siempre los límites de los arreglos antes de acceder a sus elementos.

⚠️ Casos límite

Cómo detectarla

HerramientaComandoSeñal
gaffgaff check archivo.cVariables de tamaño o índice declaradas como int.
gcc / clanggcc -Wall -Wextra -Wsign-compare -Wsign-conversion -std=c11 ...comparison of integer expressions of different signedness.
cppcheckcppcheck --enable=all archivo.cSign conversion o truncation de size_t a int.

Checklist de autocontrol

Reglas relacionadas