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:
-
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.
-
Il codice sta facendo accidentalmente qualcosa i cui effetti non sono mai stati specificati da nessuna parte e sarebbe quindi imprevedibile.
-
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.