web-dev-qa-db-fra.com

Conversion obsolète C++ de chaîne constante en 'char *'

J'ai une classe avec un private char str[256];

et pour cela j'ai un constructeur explicite:

explicit myClass(const char *func)
{
    strcpy(str,func);
}

Je l'appelle comme:

myClass obj("example");

Lorsque je compile ceci, je reçois l'avertissement suivant: 

conversion obsolète de constante de chaîne en 'char *'

Pourquoi cela arrive-t-il?

122
mkamthan

Ceci est un message d'erreur que vous voyez chaque fois que vous rencontrez une situation comme celle-ci:

char* pointer_to_nonconst = "string literal";

Pourquoi? Eh bien, C et C++ diffèrent par le type du littéral de chaîne. En C, le type est array of char et en C++, il s'agit de constant array of char. Dans tous les cas, vous n'êtes pas autorisé à modifier les caractères du littéral chaîne. Par conséquent, le paramètre const en C++ n'est pas vraiment une restriction, mais plutôt un élément de sécurité de type. Une conversion de const char* à char* n'est généralement pas possible sans conversion explicite pour des raisons de sécurité. Mais pour des raisons de compatibilité avec C, le langage C++ permet toujours d’affecter un littéral de chaîne à un char* et vous avertit que cette conversion est obsolète.

Donc, il vous manque parfois une ou plusieurs consts dans votre programme pour que le correct soit correct. Mais le code que vous nous avez montré n’est pas le problème car il ne fait pas ce genre de conversion déconseillée. L'avertissement doit provenir d'un autre endroit.

110
sellibitze

L'avertissement:

conversion obsolète de constante de chaîne en 'char *'

est donné parce que vous faites quelque part (pas dans le code que vous avez posté) quelque chose comme:

void foo(char* str);
foo("hello");

Le problème est que vous essayez de convertir un littéral de chaîne (avec le type const char[]) en char*.

Vous pouvez convertir un const char[] en const char* car le tableau se désintègre en pointeur, mais ce que vous faites est de transformer un mutable en une constante.

Cette conversion est probablement autorisée pour la compatibilité C et vous donne simplement l'avertissement mentionné.

139

En tant que répondez non. 2 de fnieto - Fernando Nieto indique clairement et correctement que cet avertissement est donné parce que quelque part dans votre code, vous faites (pas dans le code que vous avez posté) quelque chose comme:

void foo(char* str);
foo("hello");

Toutefois, si vous souhaitez que votre code ne contienne aucun avertissement, apportez les modifications correspondantes dans votre code:

void foo(char* str);
foo((char *)"hello");

Autrement dit, convertissez simplement la constante string en (char *).

79
sactiw

Il y a 3 solutions:

Solution 1:

const char *x = "foo bar";

Solution 2: 

char *x = (char *)"foo bar";

Solution 3:

char* x = (char*) malloc(strlen("foo bar")+1); // +1 for the terminator
strcpy(x,"foo bar");

Les tableaux peuvent également être utilisés à la place des pointeurs car un tableau est déjà un pointeur constant.

30
anilbey

En fait, un littéral de constante de chaîne n'est ni un const char * ni un char * mais un char []. C'est assez étrange mais écrit dans les spécifications c ++; Si vous le modifiez, le comportement n'est pas défini car le compilateur peut le stocker dans le segment de code. 

3
dan ionescu

Je résous ce problème en ajoutant cette macro au début du code, quelque part. Ou ajoutez-le dans <iostream>, hehe.

 #define C_TEXT( text ) ((char*)std::string( text ).c_str())
1
TWOPIR

Peut-être que vous pouvez essayer ceci:

void foo(const char* str) 
{
    // Do something
}

foo("Hello")

Ça marche pour moi

0
Alen Lee

Le pire dans tout cela est l’ambiguïté typique de l’abus de la "chaîne" réservée au mot, qui laisse croire à tort que "l'exemple" .c_str () résoudrait le problème.

0
Jerry Miller

Pour ce que cela vaut, je trouve cette classe d'encapsulation simple utile pour convertir des chaînes C++ en char *:

class StringWrapper {
    std::vector<char> vec;
public:
    StringWrapper(const std::string &str) : vec(str.begin(), str.end()) {
    }

    char *getChars() {
        return &vec[0];
    }
};
0
bremen_matt

J'ai aussi le même problème. Et ce que j'ai fait simplement, c'est simplement ajouter const char * au lieu de char *. Et le problème résolu. Comme d'autres l'ont mentionné ci-dessus, c'est une erreur compatible. C traite les chaînes comme des tableaux de caractères tandis que C++ les traite comme des tableaux de caractères const.

0
dilantha111