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 0x300Eh: Documentá explícitamente el comportamiento de las funciones al manejar punteros nulos como argumentos

Memoria, punteros y tipos (0x30XX)

Universidad Nacional de Río Negro

0x300Eh: Documentá explícitamente el comportamiento de las funciones al manejar punteros nulos como argumentos

Enunciado normativo

Si una función acepta punteros NULL como argumento, DEBE documentar el comportamiento que adopta en ese caso. Si NO los acepta, DEBE declararlo como precondición explícita. La ambigüedad no está permitida.

¿Por qué existe esta regla?

El problema

Recibir NULL tiene dos respuestas legítimas: tratarlo como valor válido con un significado definido (“lista vacía”) o rechazarlo como precondición incumplida. Lo que no es correcto es no decidir. Sin documentación, algunos llamadores provocarán un SIGSEGV y otros agregarán chequeos que la función ya podría garantizar.

Consecuencias de violarla

Tipo de consecuenciaEfecto concreto
Comportamiento indefinidoLa función desreferencia NULL y falla en ejecución.
Contratos duplicadosCada llamador repite la misma validación por desconfianza.
Bug silenciosoUn NULL con significado especial se interpreta como error, o al revés.

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

C11 no impone un comportamiento ante punteros nulos; cada función lo define. La cátedra exige que esa decisión sea explícita en la documentación de 0x2003h: Todas las funciones deben incluir documentación completa y estructurada, junto con los retornos de 0x3009h: Documentá explícitamente los casos en que una función puede retornar NULL.

Alcance y excepciones

Aplica a todo parámetro de tipo puntero. No aplica a parámetros que no son punteros (un size_t no admite NULL). La decisión se escribe como precondición (@pre ptr != NULL) o como nota de comportamiento.

Ejemplos exhaustivos

❌ Contraejemplo 1 — Función que no decide ni documenta

void procesar(nodo_t *nodo)
{
    nodo->dato = 0;
    nodo->sig = NULL;
}

Por qué falla: si el llamador pasa NULL, la primera línea desreferencia la dirección cero y el programa falla. La función no dice si acepta NULL ni valida su entrada. El contrato es una incógnita que sólo se descubre al ejecutar.

❌ Contraejemplo 2 — Validación defensiva que oculta el contrato

void imprimir(const lista_t *lista)
{
    if (lista == NULL)
    {
        return;
    }
    while (lista != NULL)
    {
        printf("%d\n", lista->dato);
        lista = lista->sig;
    }
}

Por qué falla: la función tolera NULL (imprime nada), pero no lo declara. El llamador que lea la firma no lo sabe y probablemente agregue su propio if, duplicando la validación. La tolerancia debe ser parte del contrato escrito.

✅ Ejemplo conforme 1 — Precondición explícita

/**
 * @brief Inicializa un nodo ya reservado.
 * @param nodo Nodo a inicializar.
 * @pre nodo != NULL (el llamador garantiza la reserva).
 * @post nodo->dato es 0 y nodo->sig es NULL.
 */
void nodo_inicializar(nodo_t *nodo)
{
    nodo->dato = 0;
    nodo->sig = NULL;
}

La precondición libera a la función de validar y deja claro al llamador que debe pasar un puntero válido. Si la precondición se rompe, es un error del llamador.

✅ Ejemplo conforme 2 — Tolerancia documentada

/**
 * @brief Imprime los elementos de una lista.
 * @param lista Lista a recorrer. Si es NULL, no imprime nada
 *              (se interpreta como lista vacía).
 * @pre Ninguna.
 */
void lista_imprimir(const lista_t *lista)
{
    while (lista != NULL)
    {
        printf("%d\n", lista->dato);
        lista = lista->sig;
    }
}

La función decide tratar NULL como lista vacía y lo documenta. El llamador no necesita un chequeo previo ni teme un fallo. La tolerancia documentada complementa la propiedad de 0x3006h: Documentá la propiedad de los recursos al utilizar punteros.

⚠️ Casos límite

Cómo detectarla

HerramientaComandoSeñal
gaffgaff check archivo.cParámetro de puntero sin @pre ni nota de tolerancia a NULL.
gcc / clanggcc -Wall -Wextra -std=c11 -fanalyzer ...possible null pointer dereference en el cuerpo.
Revisión manualLlamadores que validan lo mismo que la función.

Checklist de autocontrol

Reglas relacionadas