2013-06-18 12 views
6

Vorrei chiamare il seguente codice in C++, che non posso cambiare:Come evitare la conversione deprecato da costante di stringa a 'char *' in C++

void getAge(char *name) 
{ 
// do something 
} 

Quando chiamo con getAge("hello");, ha la seguente avvertenza:

warning: deprecated conversion from string constant to 'char*' 

ma non vi è alcun avviso nel codice C. Qual è la differenza e come posso cambiare la chiamata per evitare l'avviso in C++?

+4

Imposta il parametro della funzione a 'const char *'? –

+0

no, è la funzione definita da altri, non può essere modificata – user2131316

+1

In tal caso, lanciare l'argomento. –

risposta

17

la funzione [...] non è possibile modificare

quindi scrivere un wrapper per la funzione e copiare la stringa - o, se ti senti fortunato (= si sa che la stringa ha vinto' t essere modificato all'interno della funzione originaria), esplicitamente gettato via const-ness:

void getAge(char const* name) { 
    the_namespace::getAge(const_cast<char*>(name)); 
} 

Se non siete sicuri se la funzione modifica i suoi parametri, utilizzare qualcosa come il seguente - tuttavia, se questo è il caso quindi chiamare la funzione con una stringa letterale (getAge("hello")) sarebbe stato comunque non valido.

void getAge(char const* name) { 
    std::string buffer(name); 
    the_namespace::getAge(&buffer[0]); 
} 

Qui copiare la stringa in un buffer modificabili e passare un indirizzo al suo primo carattere alla funzione originale.

+0

@EricPostpischil E cosa significa "copia la stringa" significa, altrimenti. –

0

Si può provare getAge((char*)"hello").

+1

Solo se si sa che la funzione non tenterà di modificare la stringa. E dovresti davvero usare i cast di C++. –

+0

Questo è etichettato 'C++'. –

0

in C++ è possibile scrivere in questo modo, void getAge(string name) { // do something } e anche includere il file di intestazione #include<string> perché si sta utilizzando stringa ora

+0

il metodo void getAge() non può essere modificato – user2131316

+1

Leggi la domanda per favore ... – nouney

+1

@nouney, l'informazione "non può essere cambiata" non è ancora indicata nella domanda, ma solo nei commenti. – Steed

2

Il modo più sicuro è quello di copiare la stringa, quindi chiamare la funzione C:

void getAgeSafe(const char* name) 
{ 
    std::vector<char> tmp = name? 
    std::vector<char>(name, name+1+strlen(name)) 
    :std::vector<char>(); 

    getAge(tmp.data()); 
} 

e chiamare getAgeSafe dal codice C++.

Un modo meno sicuro che si basa sul codice C mai modificando il char* name sarebbe quello di const_cast, ancora una volta in una funzione "wrapping":

void getAgeUnsafe(const char* name) 
{ 
    getAge(const_cast<char*>(name)); 
} 

ma questa volta il nome è più spaventoso, come è l'operazione. Se chiami getAge con una stringa costante di tempo di compilazione come "bob", se getAge modifica il suo input, i risultati del comportamento non definito (questo è vero sia in C che in C++ - C++ almeno ti avvisa a riguardo).

+0

'c_str()' restituisce un 'const char *' in modo da ottenere lo stesso avviso. Passare a '& name [0]' funzionerà comunque. – SirGuy

+0

@GuyGreer oops, corretto. Anche 'data()' è 'const' per' std :: string', quindi abbiamo costruito un buffer di 'std :: vector '. (Non sono sicuro che '& name [0]' sia garantito essere terminato con null dallo standard?) – Yakk

+0

@Yakk È in C++ 11 (la terminazione null non era il problema prima di entrambi - la contiguità dello spazio di archiviazione era). Il tuo codice attuale è inutilmente complicato secondo me; basta usare il costruttore appropriato per inizializzare il vettore (ovviamente questo rende il controllo nulla impossibile o almeno più difficile). –

Problemi correlati