c++ Comportamento indefinito, non specificato e definito dall'implementazione




4 Answers

Bene, questo è fondamentalmente un semplice copia-incolla dallo standard

3.4.1 1 comportamento definito dall'implementazione comportamento non specificato in cui ogni implementazione documenta come viene effettuata la scelta

2 ESEMPIO Un esempio di comportamento definito dall'implementazione è la propagazione del bit di ordine superiore quando un intero con segno è spostato a destra.

3.4.3 1 comportamento non definito del comportamento , in seguito all'uso di un costrutto di programma non portatile o errato o di dati errati, per i quali questo Standard internazionale non impone requisiti

2 NOTA I possibili comportamenti indefiniti vanno dall'ignorare completamente la situazione con risultati imprevedibili, a comportarsi durante la traduzione o l'esecuzione del programma in un modo documentato caratteristico dell'ambiente (con o senza emissione di un messaggio diagnostico), a terminare una traduzione o un'esecuzione (con l'emissione di un messaggio diagnostico).

3 ESEMPIO Un esempio di comportamento non definito è il comportamento sull'overflow dei numeri interi.

3.4.4 1 uso del comportamento non specificato di un valore non specificato o altro comportamento in cui questo Standard Internazionale offre due o più possibilità e non impone ulteriori requisiti su cui viene scelto in ogni caso

2 ESEMPIO Un esempio di comportamento non specificato è l'ordine in cui vengono valutati gli argomenti di una funzione.

c++ c undefined-behavior c++-faq unspecified-behavior

Qual è la differenza tra comportamento non definito, non specificato e definito dall'implementazione in C e C ++?




Dal documento ufficiale C Rationale

I termini comportamento non specificato , comportamento non definito e comportamento definito dall'implementazione sono usati per categorizzare il risultato di programmi di scrittura le cui proprietà lo Standard non ha o non può descrivere completamente. L'obiettivo dell'adozione di questa categorizzazione è di consentire una certa varietà tra le implementazioni che consentono alla qualità dell'implementazione di essere una forza attiva nel mercato e di consentire alcune estensioni popolari, senza rimuovere il prestigio della conformità allo standard. L'Appendice F di Standard cataloga quei comportamenti che rientrano in una di queste tre categorie.

Il comportamento non specificato fornisce all'installatore un po 'di libertà nella traduzione dei programmi. Questa latitudine non si estende fino a non riuscire a tradurre il programma.

Il comportamento non definito consente alla licenza implementor di non rilevare alcuni errori di programma difficili da diagnosticare. Identifica inoltre le aree di possibile estensione linguistica conforme: l'implementatore può aumentare la lingua fornendo una definizione del comportamento ufficialmente indefinito.

Il comportamento definito dall'implementazione offre a un implementatore la libertà di scegliere l'approccio appropriato, ma richiede che questa scelta sia spiegata all'utente. I comportamenti definiti come definiti dall'implementazione sono generalmente quelli in cui un utente può prendere decisioni di codifica significative in base alla definizione dell'implementazione. Gli implementatori dovrebbero tenere presente questo criterio al momento di decidere in che misura una definizione di implementazione dovrebbe essere estesa. Come con un comportamento non specificato, il semplice fatto di non tradurre la sorgente che contiene il comportamento definito dall'implementazione non è una risposta adeguata.




Storicamente, sia il comportamento definito dall'implementazione sia il comportamento indefinito hanno rappresentato situazioni in cui gli autori dello Standard si aspettavano che le persone che scrivevano implementazioni di qualità usassero il giudizio per decidere quali garanzie comportamentali, se ce ne fossero, sarebbero utili per i programmi nel campo di applicazione previsto in esecuzione sul obiettivi previsti. Le esigenze del codice high-end di crimpatura del numero sono molto diverse da quelle del codice di sistemi di basso livello, e sia UB che IDB offrono agli scrittori di compilatori la flessibilità necessaria per soddisfare queste diverse esigenze. Nessuna delle due categorie impone che le implementazioni si comportino in un modo che è utile per uno scopo particolare o anche per qualsivoglia scopo. Le implementazioni di qualità che pretendono di essere adatte per uno scopo particolare, tuttavia, dovrebbero comportarsi in un modo che si addice a tale scopo, indipendentemente dal fatto che lo Standard lo richieda o meno .

L'unica differenza tra il comportamento definito dall'implementazione e il comportamento indefinito è che il primo richiede che le implementazioni definiscano e documentino un comportamento coerente anche nei casi in cui nulla potrebbe essere utile all'implementazione . La linea di demarcazione tra loro non è se sia generalmente utile per le implementazioni definire comportamenti (gli scrittori di compilatori dovrebbero definire comportamenti utili quando è pratico se lo Standard richiede o meno) ma se ci potrebbero essere implementazioni in cui la definizione di un comportamento sarebbe allo stesso tempo costosa e inutile . Un giudizio che tali implementazioni potrebbero esistere non ha alcun senso, forma o forma, implica alcun giudizio sull'utilità di supportare un comportamento definito su altre piattaforme.

Sfortunatamente, a partire dalla metà degli anni '90, i redattori di compilatori hanno iniziato a interpretare la mancanza di mandati comportamentali come un giudizio sul fatto che le garanzie comportamentali non valgono il costo anche nei campi applicativi in ​​cui sono vitali, e persino su sistemi in cui costano praticamente nulla. Invece di trattare UB come un invito a esercitare un ragionevole giudizio, gli scrittori di compilatori hanno iniziato a considerarlo come una scusa per non farlo.

Ad esempio, dato il seguente codice:

int scaled_velocity(int v, unsigned char pow)
{
  if (v > 250)
    v = 250;
  if (v < -250)
    v = -250;
  return v << pow;
}

un'implementazione a due complementi non dovrebbe richiedere alcuno sforzo per trattare l'espressione v << pow come spostamento a complemento a due, senza considerare se v fosse positivo o negativo.

La filosofia preferita da alcuni degli odierni scrittori di compilatori, tuttavia, suggerirebbe che poiché v può essere negativo solo se il programma sta per entrare in un comportamento indefinito, non c'è motivo di avere il clip del programma nell'intervallo negativo di v . Anche se lo spostamento a sinistra dei valori negativi era supportato su ogni singolo compilatore di significatività, e una grande quantità di codice esistente si basa su quel comportamento, la filosofia moderna interpreterebbe il fatto che lo standard dice che i valori negativi a spostamento di sinistra sono UB come sottintendendo che gli scrittori di compilatori dovrebbero sentirsi liberi di ignorarlo.




C ++ standard n3337 § 1.3.10 comportamento definito dall'implementazione

comportamento, per un programma ben strutturato costruire e correggere i dati, che dipende dall'implementazione e che ogni documento di implementazione

A volte C ++ Standard non impone un comportamento particolare su alcuni costrutti, ma afferma invece che un particolare comportamento ben definito deve essere scelto e descritto da un'implementazione particolare (versione della libreria). Quindi l'utente può ancora sapere esattamente come si comporterà il programma anche se Standard non lo descrive.

C ++ standard n3337 § 1.3.24 comportamento non definito

comportamento per il quale questo Standard Internazionale non impone alcun requisito [Nota: ci si può aspettare un comportamento indefinito quando questo Standard Internazionale omette qualsiasi definizione esplicita di comportamento o quando un programma utilizza un costrutto errato o dati errati. Il comportamento indefinito ammissibile va dall'ignorare completamente la situazione con risultati imprevedibili, a comportarsi durante la traduzione o l'esecuzione del programma in un modo documentato caratteristico dell'ambiente (con o senza emissione di un messaggio diagnostico), a terminare una traduzione o un'esecuzione (con l'emissione di un messaggio diagnostico). Molti costrutti di programma errati non generano un comportamento indefinito; devono essere diagnosticati. - nota finale]

Quando il programma incontra un costrutto che non è definito secondo lo standard C ++, è autorizzato a fare tutto ciò che vuole (magari mandare una mail a me o magari mandare una email a te o forse ignorare completamente il codice).

C ++ standard n3337 § 1.3.25 comportamento non specificato

comportamento, per un programma ben strutturato costruire e correggere i dati, che dipende dall'implementazione [Nota: l'implementazione non è richiesta per documentare quale comportamento si verifica. La gamma di comportamenti possibili è solitamente delineata da questo standard internazionale. - nota finale]

Lo standard C ++ non impone un comportamento particolare su alcuni costrutti, ma afferma invece che un particolare, ben definito comportamento deve essere scelto ( bot non necessario descritto ) da un'implementazione particolare (versione della libreria). Quindi, nel caso in cui non sia stata fornita alcuna descrizione, può essere difficile per l'utente sapere esattamente come si comporterà il programma.






Related