Pourquoi est-conversion de chaîne de caractères constante de 'char*' valide en C mais pas en C++
Le C++11 Norme (ISO/IEC 14882:2011) dit dans § C.1.1
:
char* p = "abc"; //valid in C, invalid in C++
Pour le C++ c'est OK comme un pointeur vers une Chaîne de caractères Littérale est nuisible puisque toute tentative de modifier conduit à un crash. Mais pourquoi est-elle valide en C?
Le C++11 dit aussi:
char* p = (char*)"abc"; //OK: cast added
Ce qui signifie que si une distribution est ajouté à la première affirmation, il devient valide.
Pourquoi le casting fait le deuxième énoncé valide en C++ et comment est-il différent du premier? N'est-il pas encore dangereux? Si c'est le cas, pourquoi ne le standard dit que c'est OK?
- C++11 n'autorise pas la première. Je n'ai aucune idée de pourquoi C fait le type d'un littéral de chaîne
char[]
en premier lieu. Le second est unconst_cast
dans le déguisement. - Il est tout simplement trop héritage du code C qui serait briser si cette règle a été modifié.
- veuillez citer le texte, où la Norme est dit que le second est
OK
. - Ah, la découverte de ce contexte, cela traite de la modification de la chaîne de caractères littérale type. L'ensemble de la distribution est le chemin de moindre résistance pour des raisons de compatibilité descendante.
- Le langage C a littéraux de chaîne avant qu'elle avait
const
, de sorte qu'ils étaient forcément pasconst
. - Le C et le C++ permet de fonte à partir de presque n'importe quel type d'un autre type. Cela ne signifie pas que ces distributions sont significatives et coffre-fort.
- Plus important encore, cette question doit être né d'une idée que les deux langues ont plus en commun que ce qu'ils font. Ceci est prouvé incorrect par le message d'erreur, alors pourquoi pensez-vous que c'est une bonne idée de demander au sujet de ces deux langues, comme si vous vous attendez à avoir un sous-ensemble commun? La programmation dans ce sous-ensemble commun est un gaspillage de votre temps, vous serez en s'appuyant sur le pire des deux mondes. Choisir l'un ou l'autre, et à utiliser l'éditeur de liens lorsque vous avez besoin de relier les modules de langues différentes.
Vous devez vous connecter pour publier un commentaire.
Jusqu'à C++03, votre premier exemple est valide, mais il a utilisé un obsolète conversion implicite--une chaîne de caractères littérale devraient être traités comme étant de type
char const *
, puisque vous ne pouvez pas modifier son contenu sans que cela provoque un comportement indéfini).Comme du C++11, la conversion implicite qui avait été désapprouvée a été officiellement retiré, donc le code qui en dépend (comme votre premier exemple) ne devrait plus compiler.
Vous l'avez remarqué une façon de permettre le code à compiler: bien que la conversion implicite a été supprimé, un explicite conversion fonctionne toujours, de sorte que vous pouvez ajouter un plâtre. Je pas, cependant, considérer cette "fixation" du code.
Vraiment fixant le code exige de changer le type du pointeur de la souris vers le bon type:
Pourquoi il a été autorisé en C++ (et l'est encore dans C): tout simplement parce qu'il y a beaucoup de code existant qui dépend de la conversion implicite, et la rupture de ce code (au moins sans avertissement officiel) apparemment, semblait à la norme comités comme une mauvaise idée.
char const *p = "abc";
est "valable et sûre dans deux C et C++", pas "valable et sûre dans soit C < / b>ou C++".const char *p = "abc"
char const *
etconst char *
sont les mêmes. Celui qui est différent estchar *const
(qui ne fonctionne pas, pour la même raison sans fioritureschar *
ne fonctionnera pas).Il est valide en C pour des raisons historiques. C traditionnellement que le type d'une chaîne littérale était
char *
plutôt queconst char *
, bien qu'il a qualifié en disant que vous n'êtes pas autorisés à modifier.Lorsque vous utilisez une distribution, vous êtes essentiellement de dire au compilateur que vous savez mieux que le type par défaut de règles de correspondance, et il rend l'attribution OK.
char[N]
et a été changé pourconst char[N]
. Il a la taille de l'information attachée à elle.char[N]
mais paschar*
par exemple"abc"
estchar[4]