OVH Cloud OVH Cloud

Affectation de "char const *" a "char *"

8 réponses
Avatar
drkm
Bonjour

Je suis tombé récemment sur le code suivant :


typedef std::map< int , char * > Map ;
typedef Map::value_type Val ;

Map m ;
m.insert( Val( 0 , "" ) ) ;

Je pensais d'abord qu'il s'agissait d'une erreur. Que le compilo
exigerait que l'on instancie std::map<> sur « char const * » au lieu
de « char * ».

Mais non, cela compile. Sans avertissement. Et plus étonnant pour
moi, il en est de même de :

char * p = "" ;

Ici aussi, j'aurais pensé que le const était nécessaire. Qu'est-ce
qui permet à un pointeur sur caractère de pointer sur un caractère
constant ? Car j'imagine que cela est lié aux chaînes de caractères
seulement.

--drkm

8 réponses

Avatar
Fabien LE LEZ
On Wed, 20 Oct 2004 00:27:25 +0200, drkm :

char * p = "" ;

Ici aussi, j'aurais pensé que le const était nécessaire.


Les chaînes de caractères statiques ne sont pas constantes. Sauf que
tenter de les modifier produit un comportement indéfini.


--
;-)

Avatar
Jean-Marc Bourguet
drkm writes:

Qu'est-ce qui permet à un pointeur sur caractère de pointer sur un
caractère constant ? Car j'imagine que cela est lié aux chaînes de
caractères seulement.


4.2/2

A+

--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org

Avatar
Horst Kraemer
Fabien LE LEZ wrote:

On Wed, 20 Oct 2004 00:27:25 +0200, drkm :

char * p = "" ;

Ici aussi, j'aurais pensé que le const était nécessaire.


Les chaînes de caractères statiques ne sont pas constantes. Sauf que
tenter de les modifier produit un comportement indéfini.


C'est la situation dans le langage C. En C++ les chaines littérales
ont le type const char [n], mais l'affectation d'un const char* à un
char* comme dans

char * p = "toto";

est légale comme exception si la source de l'affectation est une
chaine littérale.

--
Horst

--
Lâche pas la patate!


Avatar
kanze
drkm wrote in message
news:...

Je suis tombé récemment sur le code suivant :

typedef std::map< int , char * > Map ;
typedef Map::value_type Val ;

Map m ;
m.insert( Val( 0 , "" ) ) ;

Je pensais d'abord qu'il s'agissait d'une erreur. Que le compilo
exigerait que l'on instancie std::map<> sur « char const * » au lieu
de « char * ».

Mais non, cela compile. Sans avertissement. Et plus étonnant pour
moi, il en est de même de :

char * p = "" ;

Ici aussi, j'aurais pensé que le const était nécessaire. Qu'est-ce
qui permet à un pointeur sur caractère de pointer sur un caractère
constant ?


L'histoire.

Car j'imagine que cela est lié aux chaînes de caractères seulement.


Tout à fait. Il y a une règle spéciale pour que un char const* qui
provient d'une chaîne constante puisse convertir en char*,
implicitement.

Le problème, c'est qu'avant que C ait introduit le const, des choses
comme « char* p = "xxx" ; » étaient plutôt courant. Alors, pour ne pas
les casser, C a décidé que le type d'une constante de chaîne serait
char[], et non char const[]. Au départ (pré-norme), C++ a suivi la même
règle. Dans la norme, on a changé pour que les constantes de chaîne ait
le type char const[], mais pour ne pas casser le code, on a créé une
règle spéciale pour permettre les affectations comme ci-dessus.

Je crois que l'intention était que le compilateur génère un
avertissement.

--
James Kanze GABI Software http://www.gabi-soft.fr
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Avatar
kanze
Fabien LE LEZ wrote in message
news:...
On Wed, 20 Oct 2004 00:27:25 +0200, drkm :

char * p = "" ;

Ici aussi, j'aurais pensé que le const était nécessaire.


Les chaînes de caractères statiques ne sont pas constantes. Sauf que
tenter de les modifier produit un comportement indéfini.


En C++, elles ont bien le type char const[]. Il y a une règle spéciale
qui autorise la conversion, pour ne pas casser du code. Voir §2.13.4/1
pour le type, et §4.2/2 pour la règle spéciale. (On remarque que la
conversion est « deprecated ». On s'attendrait donc à ce qu'il y a un
avertissement du compilateur.)

Tu penses à C. Du C standard, évidemment : dans le C K&R, on pouvait les
écrire (avec un comportement défini).

--
James Kanze GABI Software http://www.gabi-soft.fr
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


Avatar
Andre Heinen
On Wed, 20 Oct 2004 02:47:16 +0200, Fabien LE LEZ
wrote:

On Wed, 20 Oct 2004 00:27:25 +0200, drkm :

char * p = "" ;

Ici aussi, j'aurais pensé que le const était nécessaire.


Les chaînes de caractères statiques ne sont pas constantes.


Si, leur type est const char[].

Sauf que
tenter de les modifier produit un comportement indéfini.


Parce que ce sont des constantes.

--
Andre Heinen
My address, rot13-encoded: n qbg urvara ng rhebcrnayvax qbg pbz


Avatar
Andre Heinen
On Wed, 20 Oct 2004 00:27:25 +0200, drkm
wrote:

Qu'est-ce
qui permet à un pointeur sur caractère de pointer sur un caractère
constant ? Car j'imagine que cela est lié aux chaînes de caractères
seulement.


Effectivement. Il existe une exception pour les littérales
caractère, pour des raisons historiques.

Les headers qui venaient du C contenaient souvent des
déclarations de fonctions du genre:

size_t strlen(char *str); /* sans const */

Si on avait exigé le respect de const, il n'aurait plus été
possible d'utiliser les fonctions de la bibliothèque standard C
avec les littérales caractères, ni d'ailleurs avec aucune chaîne
constante, alors que pourtant strlen() ne modifie pas son
argument.

Donc tu peux écrire
char * p = "" ;
mais à tes risques et périls. Si tu utilises p pour modifier la
chaîne constante, tu sais ce qui t'attend...
:-)

--
Andre Heinen
My address, rot13-encoded: n qbg urvara ng rhebcrnayvax qbg pbz

Avatar
Arnaud Meurgues
Andre Heinen wrote:

mais à tes risques et périls. Si tu utilises p pour modifier la
chaîne constante, tu sais ce qui t'attend...


En fait, non. ;-)

--
Arnaud
(Supprimez les geneurs pour me répondre)