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 0x2010h: Prohibición de reasignar o modificar parámetros recibidos por valor dentro de la función

Funciones, contratos y modularizacion (0x20XX)

Universidad Nacional de Río Negro

0x2010h: Prohibición de reasignar o modificar parámetros recibidos por valor dentro de la función

Enunciado normativo

NO DEBEN reasignarse ni incrementarse los parámetros recibidos por valor. Cuando se necesite un valor mutable, DEBE copiarse el parámetro a una variable local explícita antes de modificarla.

¿Por qué existe esta regla?

El problema

Un parámetro por valor es, para el llamador, un dato de entrada: su función promete no tocarlo. Que C lo reciba como copia modificable es un detalle de implementación, no una invitación a usarlo de acumulador. Si hacés n-- o limite = 0, el contrato se rompe: parece que el argumento cambió aunque no sea así. Copiar a una local con nombre propio separa el dato original del cálculo.

Consecuencias de violarla

Tipo de consecuenciaEfecto concreto
Contrato confusoEl lector cree que la función modifica el argumento del llamador.
Bug de reutilizaciónTras modificar el parámetro ya no se puede consultar el valor original.
RecursiónReasignar el parámetro altera la llamada recursiva de forma sutil.

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

En C11 los parámetros tienen duración automática y son modificables dentro de la función (§6.9.1 párrafo 9). La norma permite mutarlos; el problema es de contrato y legibilidad, no de comportamiento indefinido. La cátedra exige la copia a local para que la firma sea una promesa estable, en armonía con 0x3007h: Los argumentos de tipo puntero deben ser const siempre que la función no los modifique y 0x7001h: Siempre debés inicializar las variables a un valor conocido. Si el parámetro debe modificarse, se pasa un puntero.

Alcance y excepciones

Cubre parámetros escalares (enteros, flotantes, punteros) recibidos por valor. No se aplica a parámetros por referencia simulada con punteros: ahí modificar *p es el propósito de la función y debe documentarse.

Excepción razonable: en una función recursiva, reasignar el parámetro antes de la llamada recursiva es un patrón común (n = n - 1;), pero la cátedra prefiere pasar la expresión directamente (recursiva(n - 1)) o copiar a una local. La recursión sin caso base que describe 0x2017h: Toda funcion recursiva debe tener un caso base explicito suele venir acompañada de este descuido.

Ejemplos exhaustivos

❌ Contraejemplo 1 — Parámetro como acumulador

int calcular(int limite)
{
    while (limite > 0) {
        limite--;
    }
    return limite;
}

Por qué falla: limite deja de ser el dato de entrada y pasa a ser el acumulador. Al terminar, vale 0 siempre, y el valor original se perdió. Un lector que ve la firma no espera que la función consuma su parámetro.

❌ Contraejemplo 2 — Reasignación que oculta un error

int sumar_hasta(int n)
{
    int suma = 0;
    for (n = 1; n <= 10; n++) {
        suma += n;
    }
    return suma;
}

Por qué falla: n se reasigna en la inicialización del for y el parámetro recibido nunca se usa. La función ignora su entrada y devuelve siempre 55; reescribir el parámetro disimula que el argumento es irrelevante.

✅ Ejemplo conforme 1 — Copia a variable local

int restar_hasta_cero(int limite)
{
    int restante = limite;
    while (restante > 0) {
        restante--;
    }
    return restante;
}

limite conserva su valor de entrada y restante es explícitamente el acumulador. La firma se sostiene: la función no modifica lo que recibe.

✅ Ejemplo conforme 2 — Pasar la expresión en la recursión

static int sumar_hasta(int n)
{
    if (n <= 0) {
        return 0;
    }
    return n + sumar_hasta(n - 1);
}

La recursión avanza con n - 1 sin reasignar n. El parámetro permanece intacto durante toda la invocación y el caso base corta la cadena, evitando el desborde de pila que documenta 0x2017h: Toda funcion recursiva debe tener un caso base explicito.

⚠️ Casos límite

Cómo detectarla

HerramientaComandoSeñal
gcc / clanggcc -Wall -Wextra -Wshadow -std=c11 ...Asignación a un parámetro dentro del cuerpo.
cppcheckcppcheck --enable=style archivo.c“Parameter is modified but not used as such”.
Revisión manualparam = ... o param++ sobre un parámetro por valor.

Checklist de autocontrol

Reglas relacionadas