61 votes

Littéraux de chaîne en C

Une question rapide ... Quel est le type de littéral de chaîne en C? Est-ce char * ou const char * ou const char * const ?

61voto

Michael Burr Points 181287

En C, le type d'un littéral de chaîne est un char[] - ce n'est pas const selon le type, mais c'est un comportement indéfini d'en modifier le contenu. Aussi, 2 littéraux de chaîne qui ont le même contenu (ou suffisamment de contenu) peut ou peut ne pas partager les mêmes éléments d'un tableau.

À partir du standard C99 6.4.5/5 "Littéraux de Chaîne - Sémantique":

Dans la phase de traduction de l'7, un octet ou d'un code de valeur zéro est ajouté à chacun des caractères codés sur plusieurs octets de la séquence obtenue à partir d'une chaîne de caractères littérale ou des littéraux. Les caractères codés sur plusieurs octets de la séquence est ensuite utilisée pour initialiser un tableau de stockage statique de la durée et de longueur suffisante pour contenir la séquence. Pour la chaîne de caractères littéraux, les éléments du tableau sont de type char, et sont initialisées à chaque octet de la séquence de caractères multi-octets, pour le wide littéraux de chaîne, les éléments du tableau sont de type wchar_t, et sont initialisées avec la séquence de caractères larges...

Il n'est pas précisé si ces tableaux sont distinctes, à condition que leur éléments ont les valeurs appropriées. Si le programme tente de modifier un tel tableau, le comportement est indéfini.

En C++, "ordinaire littéral de chaîne est de type 'tableau de n const char'" (à partir de 2.13.4/1 "littéraux de Chaîne"). Mais il y a un cas spécial dans le standard C++ qui rend pointeur de littéraux de chaîne de convertir facilement à la non-const-qualifiés pointeurs (4.2/2 "Tableau de pointeur de conversion"):

Un littéral de chaîne (2.13.4) qui n'est pas d'une grande chaîne littérale peut être convertie en une valeur r de type "pointeur vers char"; une grande chaîne littérale peut être convertie en une valeur r de type "pointeur vers wchar_t".

Comme une note de côté - car les tableaux en C/C++ convertir si facilement à des pointeurs, un littéral de chaîne peut souvent être utilisé dans un pointeur de contexte, un peu comme un tableau en C/C++.


Supplémentaires éditoriaux: ce qui suit est vraiment la plupart du temps de la spéculation de ma part au sujet de la justification pour le choix le C et le C++ normes concernant littéral de chaîne types. Alors, prenez avec un grain de sel (mais s'il vous plaît commentaire si vous avez des corrections ou des détails supplémentaires):

Je pense que le C standard choisi de faire un littéral de chaîne non-const types parce qu'il a été (et est) donc beaucoup de code qui s'attend à être en mesure d'utiliser la non-const-qualifié char des pointeurs qui pointent vers des littéraux. Lorsque l' const qualificatif ai ajouté (qui, si je ne me trompe pas a été fait autour de normalisation ANSI temps, mais de temps après K&R C a été autour d'accumuler une tonne de code existant) si ils ont fait des pointeurs vers des chaînes de caractères littérales seulement en mesure d'être affecté char const* types sans un casting presque tous les programmes de l'existence aurait exigé de changer. Pas une bonne façon d'obtenir un standard accepté...

Je crois que le changement de C++ que les littéraux de chaîne sont const qualifiée a été fait principalement pour permettre une chaîne littérale afin de mieux correspondre à une surcharge qui prend un "char const*" argument. Je pense qu'il y a aussi un désir de proximité perçus comme un trou dans le système de type, mais le trou était largement ouvert par le cas particulier de la baie-de-pointeur de conversions.

L'annexe D de la norme indique que la "conversion implicite de const non-const de qualification pour les littéraux de chaîne (4.2) est obsolète", mais je pense que si beaucoup de code serait encore briser que ce sera un long temps avant que les responsables de l'implémentation du compilateur ou le comité des normes êtes prêt à réellement tirer sur la fiche (à moins que certains autres habile technique peut être imaginé - mais alors le trou serait de retour, ne serait-il pas?).

10voto

Christoph Points 64389

Un C littéral de chaîne est de type char [n]n équivaut au nombre de caractères + 1 pour tenir compte de l'implicite à zéro à la fin de la chaîne.

Le tableau sera allouée statiquement; il n'est pas const, mais une modification est un comportement indéterminé.

Si elle avait pointeur de type char * ou de type incomplète char [], sizeof pourrait ne pas fonctionner comme prévu.

Faire des littéraux de chaîne const est un C++ langage et ne fait partie d'aucune C standard.

0voto

0xfe Points 2844

Ils étaient de type char[] . Maintenant, ils sont du type const char[] .

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