C++Comportamento indefinito


introduzione

Cos'è il comportamento non definito (UB)? Secondo lo standard ISO C ++ (§1.3.24, N4296), è "un comportamento per il quale questo Standard internazionale non impone alcun requisito".

Ciò significa che quando un programma incontra UB, è permesso di fare tutto ciò che vuole. Questo spesso significa un crash, ma potrebbe semplicemente non fare nulla, far volare via demoni dal demone , o persino sembrare che funzioni correttamente!

Inutile dire che dovresti evitare di scrivere codice che invoca UB.

Osservazioni

Se un programma contiene un comportamento non definito, lo standard C ++ non pone alcun vincolo al suo comportamento.

  • Potrebbe sembrare che funzioni come previsto dallo sviluppatore, ma potrebbe anche bloccarsi o produrre risultati strani.
  • Il comportamento può variare tra le esecuzioni dello stesso programma.
  • Qualsiasi parte del programma potrebbe funzionare male, incluse le linee che precedono la linea che contiene un comportamento non definito.
  • L'implementazione non è richiesta per documentare il risultato di un comportamento non definito.

Un'implementazione può documentare il risultato di un'operazione che produce un comportamento non definito secondo lo standard, ma un programma che dipende da tale comportamento documentato non è portabile.

Perché esiste un comportamento non definito

Intuitivamente, il comportamento non definito è considerato un aspetto negativo in quanto tali errori non possono essere gestiti in modo gentile attraverso, ad esempio, gestori di eccezioni.

Ma lasciare un certo comportamento indefinito è in realtà parte integrante della promessa del C ++ "non si paga per ciò che non si usa". Un comportamento indefinito consente al compilatore di assumere che lo sviluppatore sappia cosa sta facendo e di non introdurre il codice per verificare gli errori evidenziati negli esempi precedenti.

Trovare ed evitare comportamenti indefiniti

Alcuni strumenti possono essere utilizzati per scoprire comportamenti non definiti durante lo sviluppo:

  • La maggior parte dei compilatori dispone di flag di avviso per avvisare di alcuni casi di comportamento non definito al momento della compilazione.
  • Le versioni più recenti di gcc e clang includono un cosiddetto indicatore "Undefined Behavior Sanitizer" ( -fsanitize=undefined ) che verificherà il comportamento indefinito in fase di esecuzione, a un costo prestazionale.
  • lint strumenti simili a sfilacciamenti possono eseguire analisi del comportamento indefinite più approfondite.

Comportamento indefinito, non specificato e definito dall'implementazione

Dalla norma C ++ 14 (ISO / IEC 14882: 2014) sezione 1.9 (Esecuzione del programma):

  1. Le descrizioni semantiche di questo standard internazionale definiscono una macchina astratta non parametrica parametrizzata. [TAGLIO]

  2. Alcuni aspetti e operazioni della macchina astratta sono descritti in questo Standard Internazionale come definito dall'implementazione (ad esempio, sizeof(int) ). Questi costituiscono i parametri della macchina astratta . Ogni implementazione deve includere la documentazione che descrive le sue caratteristiche e il comportamento in questi aspetti. [TAGLIO]

  3. Alcuni altri aspetti e operazioni della macchina astratta sono descritti in questo Standard Internazionale come non specificati (ad esempio, la valutazione delle espressioni in un nuovo inizializzatore se la funzione di allocazione non riesce ad allocare memoria). Ove possibile, questo standard internazionale definisce un insieme di comportamenti consentiti. Questi definiscono gli aspetti non deterministici della macchina astratta. Un'istanza della macchina astratta può quindi avere più di una possibile esecuzione per un dato programma e un dato input.

  4. Alcune altre operazioni sono descritte in questo standard internazionale come non definite (o esempio, l'effetto del tentativo di modificare un oggetto const ). [ Nota : questo Standard Internazionale non impone alcun requisito sul comportamento dei programmi che contengono comportamenti non definiti. - nota finale ]

Comportamento indefinito Esempi correlati