web-dev-qa-db-fra.com

Conversion obsolète du littéral de chaîne en «char *»

J'ai un programme qui déclare un tableau de chaînes comme ceci:

char *colors[4] = {"red", "orange", "yellow", "blue"};

Mais je reçois l'avertissement du compilateur ci-dessus. Il compile mais je préfère utiliser la méthode non obsolète (s'il y en a une). J'ai essayé de comprendre ce que cela signifie, mais je n'arrive pas à le comprendre. J'ai entendu utiliser "const" avant que "char" fonctionne, mais il serait utile que quelqu'un puisse expliquer ce que signifie l'erreur. Merci.

55
Matt

Les chaînes que vous entrez: "rouge", "organge", etc. sont "littérales", car elles sont définies dans le code du programme lui-même (elles ne sont pas lues directement à partir du disque, entrée utilisateur/stdin, etc.).

Cela signifie que si à tout moment vous essayez d'écrire sur votre colors, vous accéderez directement à votre entrée d'origine et la modifierez ainsi. Cela entraînerait des erreurs d'exécution indésirables.

Le déclarer en tant que const vous assurera que vous n'essaierez jamais d'écrire sur ce pointeur et qu'une telle erreur d'exécution peut être évitée.

const char *colors[4] = {"red", "orange", "yellow", "blue"};

Si jamais vous avez envie de modifier ces valeurs lors de l'exécution, vous devez d'abord copier les chaînes.

75
d_inevitable
"red", "orange", "yellow", "blue"

ce sont des chaînes constantes. La création d'un pointeur non const vers une chaîne constante est incorrecte, d'où l'avertissement. Pour le moment, vous recevez un avertissement, mais cela devrait être une erreur car il est obsolète en c ++ 03 et interdit en c ++ 11.

10
BЈовић

Ces réponses sont toutes correctes.

Notez que si vous avez une fonction nécessitant un tableau de caractères comme argument et que vous passez cet argument comme ceci:

foo ("bar");

le même avertissement s'affichera. Dans ce cas, vous pouvez soit:

1) Modifiez-le comme ceci, comme expliqué dans la première réponse:

void foo (char[] str) { printf(str); }

const char param[] = "bar";
foo (param);

2) Envisagez d'utiliser une chaîne standard C++, comme ceci:

void foo (std::string theParam) { std::cout << theParam; }

foo ("bar");

À mon humble avis, tant qu'aucun problème de performance réel n'est concerné et que vous ne travaillez pas avec les bibliothèques C, ou si vous créez une bibliothèque C++ pour les autres, vous devriez plutôt travailler avec des chaînes immuables C++ et leur ensemble de fonctionnalités.

Si Unicode est une exigence, le support en C++ est "terrible" comme expliqué ici . Cette question vous donne quelques indices (principalement: utilisez IBM ICU bibliothèque). Si vous avez déjà Qt dans votre projet, QString fera aussi le astuce, tout comme Gettext.

4
tiktak