2014-10-21 10 views
5

Sto guardando un codice di esempio per un'API che sto per iniziare a utilizzare. Il seguente schema mi ha un po 'confuso:C'è un motivo per usare const_cast su una stringa letterale in questo codice?

char* str; 
str = const_cast<char*>("Hello World"); 

printf("%s ", str); 

(. In realtà c'è un'istruzione case enorme in cui str viene assegnato in ogni caso)

Nota che printf prende const char*. C'è qualche ragione ragionevole per questa conversione convoluta? Gli autori di questo codice stanno applicando molti trucchi orientati alla prestazione altrove, ma non c'è alcuna spiegazione per quello che sta succedendo qui.

Il mio istinto è quello di cambiare questo codice per:

const char* str; 
str = "Hello World"; 

printf("%s ", str); 

Mi sto perdendo qualcosa?

+6

Sostituirlo. Il codice originale è pericolosamente vicino al terreno di comportamento non definito. –

+0

Sì, 'puts' non fa esattamente la stessa cosa. Perchè 'puts' sarebbe una scelta migliore in altre situazioni? –

+0

@ValekHalfHeart Oh, sì, era una sciocchezza, non importa. – Columbo

risposta

3

Una stringa letterale è un non-const char[N] in C e uno const char[N] in C++. Le versioni precedenti dello standard C++ rendevano speciale una stringa letterale const da assegnare a un non-const char* per retrocompatibilità con C. Tuttavia, questo comportamento era deprecato in C++ 03 e ora è illegale in C++ 11 senza un cast esplicito, come quello mostrato.

Se si è interessati solo a C++ 11, è necessario modificare str in const char*. Altrimenti, puoi usare il cast per la compatibilità con le versioni precedenti.

+1

Interessante. Sospetto che questo sia il retroscena. Il codice in questione ha un sacco di verruche multipiattaforma. Sto usando C++ 11, ma questo codice risale probabilmente prima del C++ 03. Qual è la distinzione che fai tra const e readonly? Mi sono chiesto spesso cosa succederebbe se si tentasse di modificare una stringa letterale. –

+0

@Drew La lingua potrebbe consentire di modificarlo, ma ciò non significa che sia sicuro farlo. –

+0

@remyabel, d'accordo. Ma cosa stai effettivamente cambiando in questo caso? Se una stringa letterale è duplicata nel codice e il compilatore li consolida all'interno dell'eseguibile, cambierebbe un'altra istanza? Potrebbe proteggere quell'area della memoria? Suppongo che la risposta a queste domande sia 'dipende' :) –

2

L'unico motivo possibile potrebbe essere che printf richiede char* in alcune implementazioni particolari. Che, dopo alcune ricerche, sembra non essere il caso. D'altra parte, avere un puntatore a non-const char puntare a una stringa letterale è pericoloso poiché la modifica di una stringa letterale innesca un comportamento indefinito. Se funziona senza il cast non c'è motivo di averlo lì e dovresti cambiarlo subito.

Problemi correlati