2013-03-12 22 views
13

Secondo la norma C++ di tipo letterale stringa è array of const charC++ const correttezza con le stringhe

auto constStr = "aaa"; 
char* nonConstStr = constStr; //Error here, cannot convert from 'const char *' to 'char *' 
char* stillNonConstStr = "aaa"; //Why I don't have error here? 

Si può spiegare il motivo per cui me sulla linea 3 non ottengo un errore?

+1

@Rapptz Non riesco a trovare la stessa clausola che consente la stessa "conversione retrocompatibilità" nello standard C++ 11. Suppongo che sia stato rimosso, quindi la domanda collegata non è realmente un duplicato al giorno d'oggi. – Angew

+0

Perché è preferibile consentirlo come è stato consentito storicamente piuttosto che rompere migliaia di programmi esistenti. –

+3

@Rapptz In che modo una domanda + risposta su C è una copia di una su C++? Soprattutto in un'area in cui le due lingue in realtà differiscono. – Angew

risposta

12

In C++ 03, esisteva una regola speciale ([conv.array] §2) che consentiva la conversione di stringhe letterali in tipo char*.

In C++ 11 questa regola non esiste più. In altre parole, il tuo codice è valido C++ 03, ma C++ 11 non valido.

+0

* illformato * o * deprecato * C++ 11. Non valido Questo sarebbe comunque compilato per ragioni storiche. [Vedi qui senza -Wall] (http://ideone.com/Itv8Hz) o [qui con -Wall -Werror] (http://coliru.stacked-crooked.com/view?id=bf8d5e2bc40d1220813841a85bfdbe25-18aa934a8d82d638dde2147aa94cac94) – Rapptz

+7

@ Rapptz: non valido == non valido. –

+2

@Rapptz Attenzione, * illformed *! = * Deprecato *, * "deprecato" * le cose funzionano ma sono scoraggiate, * "illformed" * (e * "invalid" *, come * Benjamin * dice) cose * non * lavoro. –

14

Ragioni storiche. Prima era consentito, e molto comune, assegnare da una stringa letterale a uno char*, anche se il tipo di stringa letterale è una matrice di const char. Credo che provenga da giorni nello C in cui il numero const non esisteva, ma non citarlo. Successivamente è stato deprecato, ma ancora consentito per non rompere le basi di codice che lo utilizzavano. Tale indennità non si estende per consentire a di inizializzarsi da const char* (né da array di const char che non sono letterali), motivo per cui la seconda riga non riesce. In C++ 11, la conversione da stringa letterale a char* è vietata, ma il compilatore potrebbe non applicarla ancora.