2013-03-12 3 views
13

Selon la norme C d'un type chaîne littérale est array of const charconst C++ avec exactitude littéraux chaîne

auto constStr = "aaa"; 
char* nonConstStr = constStr; //Error here, cannot convert from 'const char *' to 'char *' 
char* stillNonConstStr = "aaa"; //Why I don't have error here? 

Pouvez-vous me expliquer pourquoi s'il vous plaît sur la 3ème ligne je ne reçois pas une erreur?

+1

@Rapptz Je n'arrive pas à trouver la même clause permettant la même "conversion rétrocompatibilité" dans la norme C++ 11. Je suppose qu'il a été supprimé, donc la question liée n'est pas vraiment un doublon de nos jours. – Angew

+0

Parce qu'il est préférable de le laisser comme il a été autorisé historiquement que de casser des milliers de programmes existants. –

+3

@Rapptz Comment une question + réponse à propos de C est-elle une copie de C++? Surtout dans une région où les deux langues diffèrent réellement. – Angew

Répondre

12

En C++ 03, il existait une règle spéciale ([conv.array] §2) qui permettait de convertir les chaînes littérales en type char*.

En C++ 11, cette règle n'existe plus. En d'autres termes, votre code est valide C++ 03, mais C++ 11 non valide.

+0

* illformed * ou * déconseillé * C++ 11. Non invalide. Cela compilerait encore pour des raisons historiques. [Voir ici sans -Wall] (http://ideone.com/Itv8Hz) ou [ici avec -Wall -Werror] (http://coliru.stacked-crooked.com/view?id=bf8d5e2bc40d1220813841a85bfdbe25-18aa934a8d82d638dde2147aa94cac94) – Rapptz

+7

@ Rapptz: mal formé == invalide. –

+2

@Rapptz Méfiez-vous, * illformed *! * * Déconseillé *, * "déconseillé" * les choses fonctionnent mais sont découragées, * "illformed" * (et * "invalide" *, comme * Benjamin * dit) choses * ne * travail. –

14

Raisons historiques. Il était permis, et très commun, d'assigner d'un littéral de chaîne à un char*, même si le type d'un littéral de chaîne est un tableau de const char. Je crois que cela vient des jours Cconst n'existait pas, mais ne me citez pas là-dessus. Il a été déprécié plus tard, mais toujours autorisé afin de ne pas casser les bases de code qui l'ont utilisé. Cette allocation ne s'étend pas pour permettre l'initialisation de char* à partir de const char* (ni à partir de tableaux de constchar qui ne sont pas des littéraux), ce qui explique pourquoi votre deuxième ligne échoue. En C++ 11, la conversion de chaîne littérale à char* est interdite, mais votre compilateur peut ne pas l'appliquer pour le moment.