ProgrammazioneSviluppatore C

Che cosa si intende per 'undefined behavior' nel linguaggio C? Fornisci esempi della sua insorgenza e modi per minimizzare tali problemi.

Supera i colloqui con l'assistente IA Hintsage

Risposta.

Undefined Behavior (UB) è il comportamento di un programma il cui risultato non è definito dallo standard del linguaggio C. Il compilatore o il sistema possono eseguire qualsiasi azione, da un errore impercettibile a un completo crash o corruzione dei dati.

Cause tipiche di UB:

  • Accesso oltre i limiti di un array
  • Dereferenziazione di un puntatore non inizializzato/invalido
  • Divisione per 0
  • Modifica di costanti

Come minimizzare UB:

  • Inizializzare sempre le variabili
  • Controllare gli indici degli array
  • Utilizzare analizzatori di codice statici e dinamici (ad esempio, valgrind, AddressSanitizer)

Esempio di codice:

int arr[5]; arr[10] = 0; // UB — accesso oltre i limiti dell'array int* p = NULL; *p = 42; // UB — dereferenziazione di un puntatore NULL

Domanda trabocchetto.

Domanda: Come si comporterà il programma se si esegue una divisione di un numero intero per zero?

Risposta: Secondo lo standard C (ISO C99 6.5.5), la divisione per 0 è un comportamento indefinito. È possibile un crash, l'emergere di spazzatura o anche un'uscita "logicamente corretta", ma lo standard non garantisce alcun risultato.

Esempio di codice:

int a = 10, b = 0; printf("%d", a / b); // Undefined behavior

Storia

In uno dei progetti su sistemi embedded, un programmatore ha scritto un ciclo su un array, passando accidentalmente oltre il suo limite di un elemento. L'applicazione ha funzionato normalmente, ma dopo un mese ha iniziato a verificarsi la corruzione di altri dati in memoria (errori temporanei, difficile riproducibilità). Il problema è stato trovato solo dopo un attento review e verifiche con un analizzatore statico.


Storia

Un sviluppatore si era basato sul fatto che il risultato della dereferenziazione di un puntatore NULL provocasse sempre un crash, e perciò non aveva aggiunto controlli per NULL. Tuttavia, su una piattaforma rara, ciò portava a una modifica non corretta (ma non fatale) della memoria, che rompeva altre strutture e causava bug difficili da tracciare.


Storia

Nella generazione di numeri pseudocasuali era utilizzata la divisione, e con alcuni valori di argomenti di input si verificava la divisione per 0. Su la maggior parte delle piattaforme, il programma semplicemente "crashava", ma su una di esse il risultato era un numero non corretto, il che portava all'impossibilità di riprodurre i bug tra ambienti diversi.