Coerenza del comportamento non definito

2

Se c'è un bug che attiva un comportamento indefinito in un pezzo di codice, il comportamento indefinito è coerente ogni volta che lo esegue? e cambia ogni volta che lo compila?

Ad esempio se hai un codice C che manipola le stringhe. Lo compili, lo esegui 3 volte e l'output è coerente con caratteri strani come ABCE*D-*+ĚĚĚĚĚĚĚĚĚĚĚ . Lo compili di nuovo e la prossima volta lo eseguirà 3 volte si blocca.

Mi dispiace se la descrizione è un po 'ambigua, mentre sto cercando di capirlo da solo.

    
posta Vikaton 13.02.2016 - 17:13
fonte

2 risposte

11

No. La coerenza del comportamento non definito è indefinita.

Parlando praticamente, quando hai causato un comportamento indefinito dereferenziando un puntatore nullo, puoi probabilmente aspettarti risultati abbastanza deterministici (errore di segmentazione) almeno sullo stesso computer, perché quel computer è stato costruito per comportarsi in questo modo per il puntatore nullo dereferenziazioni.

Ma quando lo hai causato dereferenziando i puntatori non inizializzati, se il dereferimento che ne deriva è addirittura "fisicamente" possibile dipenderà da ciò che è un valore non specificato e non inizializzato, che può dipendere da quale codice è stato eseguito prima e con quale utente input e in quale ordine. Come un lancio di dadi, non è in realtà casuale, ma non è nemmeno deterministico né utile. Aggiungi ottimizzazioni nel mix e non è più pratico tentare di razionalizzare qualcosa di questo .

Ecco perché tendiamo a non entrare in ulteriori dettagli sulle cause di sintomi specifici di comportamento non definito; raramente c'è un punto.

    
risposta data 13.02.2016 - 17:34
fonte
-3

In base alla Razionale pubblicata per lo standard C:

The terms unspecified behavior, undefined behavior, and implementation-defined behavior are used to categorize the result of writing programs whose properties the Standard does not, or cannot, completely describe. The goal of adopting this categorization is to allow a certain variety among implementations which permits quality of implementation to be an active force in the marketplace as well as to allow certain popular extensions, without removing the cachet of conformance to the Standard. [italics in original]

Lo standard usa quindi il termine comportamento indefinito per riferirsi sia a costrutti che generalmente non avrebbero senso su tutte le implementazioni, sia a costrutti che alcune implementazioni elaboreranno come "estensioni popolari", ma altre no.

Senza sapere cosa sta facendo il tuo particolare codice, potrebbe essere una delle tre situazioni:

  1. Il tuo codice si basa su un compilatore per supportare una "estensione popolare", ma nella sua configurazione attuale no. Alcune di tali estensioni sono state documentate nelle specifiche del linguaggio autorevole precedenti allo standard (ad esempio il 1974 "C Reference Manual", o K & R "The C Programming Language", prima e seconda edizione) ma non erano considerate estensioni al momento. Invece, a giudicare dal Razionale, gli autori dello Standard intendevano dire che i compilatori non erano tenuti a comportarsi esattamente come prima specificato nei casi d'angolo, in cui ciò sarebbe costoso e inutile, e non pensava fosse necessario dire esplicitamente i compilatori dovrebbero comunque supportare i comportamenti quando i compilatori pratici e utili, ma attesi, lo facciano in caso di mandato o meno.

  2. Il codice sta facendo accidentalmente qualcosa i cui effetti non sono mai stati specificati da nessuna parte e sarebbe quindi imprevedibile.

  3. Il codice sta facendo qualcosa che lo standard consente alle implementazioni di elaborare in due o più modi diversi, scelti in modo non specificato (ad esempio dato x=f()+g(); , le implementazioni possono chiamare f() e poi g() , o chiamare g() e poi f() , scegliendo in qualsiasi modo ritengano opportuno), e il suo comportamento è definito dallo Standard o l'implementazione come eseguita in uno dei modi in cui funziona.

In situazioni come la tua, il problema è più spesso # 1, # 2, o una combinazione di questi, che # 3. Mentre # 2 è forse più comune di # 1, i compilatori che attribuiscono un valore di "ottimizzazione" superiore alla compatibilità con il codice esistente stanno diventando sempre più comuni.

    
risposta data 04.07.2018 - 19:53
fonte

Leggi altre domande sui tag