2011-12-20 25 views
8

Sono sicuro che il seguente codice non dovrebbe essere compilato. Ma, in g ++, lo fa compilare! Vedi compilare a http://codepad.org/MR7Dsvlz.Un cast da (puntatore a const) a (puntatore a non-const) C++ non valido?

Il codice:

#include <iostream> 

using namespace std; 

int main() { 
    int x = 32 ; 
    // note: if x is, instead, a const int, the code still compiles, 
    // but the output is "32". 

    const int * ptr1 = & x ; 

    *((int *)ptr1) = 64 ; // questionable cast 
    cout << x ;   // result: "64" 
} 

è G ++ per errore compilando questo?

+0

Se vuoi eliminare la costanza (e sei sicuro che sia consentita) il modo C++ idiatico per farlo è con 'const_cast (ptr1)' - anche se il cast di C funzionerà anche, come hai appena visto . –

+1

Questo utile da leggere: http://stackoverflow.com/questions/357600/is-const-cast-safe – Pubby

risposta

9

No. Secondo §5.4.4 dello standard C++, i calchi che possono essere eseguite da un cast C-style sono:

— a const_cast (5.2.11), 
— a static_cast (5.2.9), 
— a static_cast followed by a const_cast, 
— a reinterpret_cast (5.2.10), or 
— a reinterpret_cast followed by a const_cast 

Questo è ampiamente conosciuto come "gettato via const -ness" e il compilatore non sarebbe conforme a quella parte dello standard se non ha compilato quel codice.

Come fa notare ildjarn, la modifica di un oggetto const tramite la trasmissione di distanza const è un comportamento non definito. Questo programma non mostra un comportamento indefinito perché, nonostante un oggetto puntato dal puntatore-a-const, l'oggetto stesso non è const (grazie a R.Martinho e eharvest per correggere la mia cattiva lettura).

+0

"No." - Quindi g ++ dovrebbe aver compilato il codice? "il compilatore non sarebbe conforme a quella parte dello standard se non compilasse quel codice." - Quindi g ++ è conforme a quella parte dello standard? –

+0

@noshenim la tua domanda era "È g ++ in errore compilando questo?" a cui ho risposto "No". Quindi g ++ dovrebbe, e lo fa, compilare il codice ed è conforme a quella parte dello standard. –

+3

Noshenim, hai posto domande contraddittorie. Qualsiasi risposta * si * alla domanda del titolo è stata una * no * risposta alla domanda sul corpo. Per favore sii più attento la prossima volta. –

3

No. g ++ non ha sbagliato compilando il codice. il cast che hai fatto è valido.

(int *)ptr1 è un cast di c. l'equivalente in C++ è const_cast<int*>(ptr1). il secondo stile è più chiaro da leggere.

ma, la necessità di eseguire questa trasmissione (per modificare una variabile const) presenta un problema nel progetto.

1

La riga *((int *)ptr1) = 64 equivale a *(const_cast<int*>(ptr1)) = 64 Il const_cast è il primo cast eseguito quando si utilizza la notazione del cast.

Problemi correlati