assert în C

Verifică în timpul rulării o condiție care trebuie să fie mereu adevărată și oprește programul cu un mesaj dacă nu este.

Sintaxă
#include <assert.h>
void assert(expresie);   // macro
// cu #define NDEBUG înainte de #include <assert.h>, assert nu mai face nimic

Ce face assert

assert(conditie) evaluează condiția. Dacă este adevărată, nu se întâmplă nimic. Dacă este falsă, afișează pe stderr condiția, fișierul, funcția și linia, apoi oprește programul cu abort().

Se folosește pentru greșeli de programare, lucruri care „nu se pot întâmpla” dacă restul codului este corect: un pointer care nu are voie să fie NULL, un indice în limite. Nu se folosește pentru erori normale (fișier lipsă, date greșite de la utilizator), care trebuie tratate.

Dacă definești NDEBUG înainte de #include <assert.h> (sau compilezi cu -DNDEBUG, cum fac multe build-uri de producție), toate apelurile assert dispar. De aceea condiția nu trebuie să aibă efecte (assert(x++ > 0) schimbă comportamentul programului). Pentru verificări la compilare există static_assert.

Parametri

Parametru Descriere
expresie Condiția care trebuie să fie adevărată (diferită de 0).

Ce returnează

Nimic. Dacă expresia este falsă, programul se oprește.

Exemple

Exemplul 1: Condiții care trec

#include <assert.h>
#include <stdio.h>

static double media(const int *note, int n) {
    assert(note != NULL);
    assert(n > 0);
    int suma = 0;
    for (int i = 0; i < n; i++) {
        suma += note[i];
    }
    return (double)suma / n;
}

int main(void) {
    int note[] = {9, 8, 10};
    printf("Media: %.2f\n", media(note, 3));
    return 0;
}

Rezultat

Media: 9.00

Exemplul 2: O condiție care nu trece

Programul se oprește la assert, iar linia de după nu mai rulează. Mesajul este cel afișat pe macOS; formatul diferă puțin pe alte sisteme.

#include <assert.h>
#include <stdio.h>

static void seteaza_nota(int nota) {
    assert(nota >= 1 && nota <= 10);
    printf("Nota %d salvată\n", nota);
}

int main(void) {
    seteaza_nota(9);
    seteaza_nota(11);
    return 0;
}

Ieșire în terminal

$ ./program
Nota 9 salvată
Assertion failed: (nota >= 1 && nota <= 10), function seteaza_nota, file exemplu.c, line 5.
Abort trap: 6

Exemplul 3: assert dezactivat cu NDEBUG

Cu NDEBUG definit, verificarea nu mai există, iar programul continuă cu o valoare greșită.

#define NDEBUG
#include <assert.h>
#include <stdio.h>

int main(void) {
    int stoc = -3;
    assert(stoc >= 0);
    printf("Stoc: %d (assert a fost ignorat)\n", stoc);
    return 0;
}

Rezultat

Stoc: -3 (assert a fost ignorat)

Greșeli frecvente

  • Pui cod necesar în assert: assert(fclose(f) == 0);. Cu NDEBUG, fișierul nu mai este închis.
  • Folosești assert pentru a verifica intrarea utilizatorului. În build-ul de producție verificarea dispare; tratează eroarea cu if.

Comenzi înrudite

  • static_assert: Verifică o condiție la compilare: dacă este falsă, programul nu se compilează și apare mesajul tău.
  • exit, atexit și EXIT_SUCCESS: Oprește programul din orice funcție, cu un cod de ieșire; atexit înregistrează funcții de rulat la final.
  • #if, #ifdef, #ifndef: Compilare condiționată: preprocesorul păstrează sau elimină bucăți de cod în funcție de macro definite sau de valoarea lor.
  • #define: Definește o macro: un nume pe care preprocesorul îl înlocuiește cu textul dat, înainte ca programul să fie compilat.
  • Comportament nedefinit (undefined behavior): Situațiile pentru care standardul C nu spune ce se întâmplă: programul poate merge, poate da rezultate greșite sau se poate opri.