2015-10-28 6 views
13

Secondo standard C++, è obbligatorio per ogni implementazione di documentare il "comportamento definito dall'implementazione":Documentazione della conversione "non valido valore di puntatore" in C++ implementazioni

1.3.11 [defns.impl.defined]comportamento definito dall'implementazione

comportamento per un costrutto programma ben formato e dati corretti, che dipende dalla attuazione e che ogni documenti di attuazione

e lettura di un valore di puntatore valido ha un comportamento definito dall'implementazione (vedi 4.1 Ivalue a rvalue conversione [conv.lval]):

se l'oggetto a cui il glvalue riferisce contiene un valore di puntatore valido (3.7.4.2, 3.7 .4.3), il comportamento è definito dall'implementazione.

(citazione da un progetto di n4527, ma verbosità che "Indirection attraverso un valore di puntatore non valido e il superamento di un valore di puntatore non valido a una funzione deallocazione sono indefinito comportamento. Ogni altro uso di un valore di puntatore non valido ha un comportamento definito dall'implementazione. "è stato in 3.7.4.2 Funzioni di deallocazione [basic.stc.dynamic.deallocation] poiché almeno la bozza n3485)

Tuttavia, molte implementazioni popolari non definiscono questo comportamento e molti esperti descrivono questo comportamento come" comportamento non definito ".

Una probabile causa di omissione di documentazione chiara è che, per quanto posso determinare, la valutazione dei "valori di puntatore non validi" non è presente nell '"Indice di comportamento definito dall'implementazione" che appare nelle bozze standard dopo le appendici.

Si tratta di un difetto dello standard e sono disponibili relazioni sui difetti o azioni di comitato aperte da C++ 14 in merito?

+0

Mi sembra la parte che le implementazioni devono definire è questa: * Alcune implementazioni potrebbero definire che copiare un valore di puntatore non valido causa un errore di runtime generato dal sistema. * (Nota a piè di pagina sotto §3.7.4.3). Dovresti essere in grado di determinare dalla documentazione del tuo processore se determinati pattern di bit caricati in un registro di indirizzi causeranno un errore. – Praetorian

+4

Quindi la tua domanda è: perché questo non è documentato nell'indice * del comportamento definito dall'implementazione *? –

+0

@Praetorian: il comportamento dei programmi C++ non è certamente identico al comportamento documentato dal fornitore della CPU (si consideri una condizione di loop che termina solo con il wrapper integrale-intero - la CPU può ben definire che avvenga il wraparound, ma l'ottimizzatore C++ è perfettamente ha il diritto di trattarlo come un ciclo infinito) –

risposta

9

CWG #1438 cambiato la semantica riguardante valori puntatore non valido:

L'attuale standard dice che qualsiasi uso di un valore di puntatore non valido produce comportamento non definito (3.7.4.2 [basic.stc.dynamic.deallocation] paragrafo 4). Ciò include non solo il dereferenziamento del puntatore ma anche solo recuperando il suo valore. Il motivo di questa limitazione draconiana è che alcune architetture in passato utilizzavano registri di indirizzi dedicati per carichi puntuali e archivi e potevano commettere errori se, ad esempio, un numero di segmento in un puntatore non era correntemente mappato .

Non è chiaro se tali restrizioni siano necessarie con le architetture attualmente in uso o ragionevolmente previste. Questo dovrebbe essere investigato per vedere se la restrizione può essere allentata per applicare solo al dereferenziamento del puntatore.

La variazione [conv.lval] è la risoluzione di CWG #616, che essenzialmente ha adottato il sopra.
Il passaggio da UB a un comportamento definito dall'implementazione è stato intenzionale, quindi presumo che l'assenza di questo paragrafo nell'indice sia una svista.