63 votes

Est-ce mauvais pour déclarer un style C chaîne sans const? Si oui, pourquoi?

Faire cela en C++

char* cool = "cool";

compile bien, mais me donne un avertissement:

obsolète conversion de chaîne de caractères de type char*.

Je n'aurais jamais volontairement utiliser un style C chaîne de plus de std::string, mais juste au cas où je me suis posé cette question:

est-ce une mauvaise pratique de déclarer un style C chaîne sans l' const modificateur? Si oui, pourquoi?

59voto

aschepler Points 23731

Oui, cette déclaration est une mauvaise pratique, car il permet à de nombreuses manières de accidentellement provoquer un Comportement Indéfini par écrit à un littéral de chaîne, y compris:

cool[0] = 'k';
strcpy(cool, "oops");

D'autre part, ce qui est parfaitement correct, car il alloue un non-const tableau de caractères:

char cool[] = "cool";

17voto

Zack Points 44583

Oui, en C++, vous devez toujours vous référer à des littéraux de chaîne avec des variables de type const char * ou const char [N]. C'est aussi des bonnes pratiques lors de l'écriture du nouveau code C.

Les littéraux de chaîne sont stockées dans la mémoire en lecture seule, lorsque cela est possible; leur type est correctement const-qualifiés. C, mais pas en C++, comprend une compatibilité descendante verrue où le compilateur donne le type char [N] , même si elles sont stockées dans la mémoire en lecture seule. C'est parce que les littéraux de chaîne sont plus âgés que l' const de qualification. const a été inventé dans la perspective de ce qui est maintenant appelé "C89" -- la précédente "K&R" forme de la langue n'en ont pas.

Certains compilateurs C comprennent une option de mode de compatibilité descendante verrue est désactivé, et char *foo = "..."; vous obtiendrez le même ou similaire diagnostic qu'il fait en C++. GCC sorts de ce mode -Wwrite-strings. Je le recommande fortement pour le nouveau code; toutefois, de l'allumer pour l'ancien code est susceptible de nécessiter une quantité énorme de scutwork pour très peu d'avantages.

14voto

milleniumbug Points 4445

Elle est mauvaise. C'est très mauvais. Pour l'instant, ce n'est pas possible de faire de plus, en C++11.

La modification de la mémoire d'un littéral de chaîne est un comportement indéterminé.

13voto

NathanOliver Points 10062

Tout d'abord, char* cool = "cool"; n'est pas standard C++. Un littéral de chaîne a le type d' const char[n]. De sorte que la ligne de code pauses const-correctness et ne devrait pas compiler. Certains compilateurs comme GCC permettre cela, mais d'émettre un avertissement, comme il est tenu de C. MSVC émettra une erreur, puisqu'il est une erreur.

Deuxièmement, pourquoi ne pas laisser le compilateur de travail pour vous? Si elle est marquée const , alors vous obtiendrez une belle erreur de compilation si vous avez accidentellement essayer de la modifier. Si vous ne le faites pas, alors vous pouvez obtenir une très mauvaise erreur d'exécution qui peut être beaucoup plus difficile à trouver.

7voto

ensc Points 2056

Il est mauvais parce que les constantes de chaîne peut contenir qu'une seule fois par binaire (mot-clé: stringtable, .strtab). E. g. dans

char *cool = "cool";
char *nothot = "cool";

les deux variables peuvent pointer vers le même emplacement mémoire. Modifier le contenu de l'un d'entre eux est susceptible d'altérer les autres trop, de sorte qu'après

strcpy(nothot, "warm");

votre cool devient "chaud".

En bref, c'est un comportement indéterminé.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X