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 0x3007h: Los argumentos de tipo puntero deben ser const siempre que la función no los modifique

Memoria, punteros y tipos (0x30XX)

Universidad Nacional de Río Negro

0x3007h: Los argumentos de tipo puntero deben ser const siempre que la función no los modifique

Enunciado normativo

Todo parámetro de tipo puntero cuyo objeto apuntado NO sea modificado por la función DEBE declararse con const sobre el tipo apuntado (const T *param). El calificador DEBE ubicarse antes del tipo base, conforme a 0x3017h: Orden canónico de calificadores: ‘const tipo’ en lugar de ‘tipo const’.

¿Por qué existe esta regla?

El problema

const en un parámetro de puntero es un contrato verificable por el compilador: promete que la función no escribirá a través de ese puntero. Sin el calificador, el llamador no distingue una función que lee de una que modifica, y además no puede pasarle datos const ni literales. El calificador no limita al llamador: lo habilita a usar sus datos de sólo lectura con más funciones.

Consecuencias de violarla

Tipo de consecuenciaEfecto concreto
Contrato débilEl llamador no sabe si sus datos serán alterados.
Restricción inversaNo se pueden pasar literales de cadena ni objetos const a la función.
Bug silenciosoUna escritura accidental modifica datos del llamador sin advertencia.

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

C11 §6.7.3 define el calificador const: un lvalue const no puede modificarse. Aplicado al tipo apuntado, impide escrituras a través del puntero. La cátedra lo exige como estilo defensivo: el contrato debe ser lo más restrictivo posible.

Alcance y excepciones

Aplica a parámetros de puntero, incluidos punteros a structs y a void. No aplica cuando la función modifica el objeto apuntado, ni al propio puntero cuando se reasigna localmente (T *const, otro contrato).

Ejemplos exhaustivos

❌ Contraejemplo 1 — Función de impresión sin const

void imprimir_texto(char *cadena)
{
    printf("%s\n", cadena);
}
imprimir_texto("hola");

Por qué falla: aunque imprimir_texto no escribe, su firma no lo dice. Pasar el literal "hola" (de tipo char[5], almacenado en memoria de sólo lectura) no compila en C moderno porque el parámetro no es const. El contrato quedó más restrictivo que la realidad.

❌ Contraejemplo 2 — Recorrido que no modifica pero no es const

size_t contar_pares(int *valores, size_t cantidad)
{
    size_t pares = 0;
    for (size_t i = 0; i < cantidad; i++)
    {
        if (valores[i] % 2 == 0)
        {
            pares++;
        }
    }
    return pares;
}

Por qué falla: la función sólo lee valores, pero su firma sugiere que podría modificarlo. El llamador que tenga un arreglo const no podrá usarla, y quien lea la firma deberá revisar el cuerpo para confiar.

✅ Ejemplo conforme 1 — const sobre el tipo apuntado

void imprimir_texto(const char *cadena)
{
    printf("%s\n", cadena);
}
size_t contar_pares(const int valores[], size_t cantidad);

Ambas firmas declaran explícitamente que no modifican lo apuntado: la primera con cuerpo y la segunda como prototipo. El compilador verifica el contrato y el llamador puede pasar datos const o literales.

✅ Ejemplo conforme 2 — Distinguir entrada de salida

void sumar_vectores(const double *a, const double *b, double *resultado,
                    size_t cantidad)
{
    for (size_t i = 0; i < cantidad; i++)
    {
        resultado[i] = a[i] + b[i];
    }
}

Los dos operandos de entrada son const; el destino no lo es porque se escribe. La firma completa comunica el flujo de datos sin leer el cuerpo. Si el destino fuera también const, el compilador rechazaría la asignación.

⚠️ Casos límite

Cómo detectarla

HerramientaComandoSeñal
gaffgaff check archivo.cParámetro de puntero sin const en función que no escribe lo apuntado.
gcc / clanggcc -Wall -Wextra -Wwrite-strings -Wcast-qual ...discarding 'const' qualifier al llamar con datos de sólo lectura.
cppcheckcppcheck --enable=style archivo.cParameter 'x' can be declared as pointer to const.

Checklist de autocontrol

Reglas relacionadas