OVH Cloud OVH Cloud

empêcher la compilation de 'x'+"yz" ?

50 réponses
Avatar
Philippe Guglielmetti
J'ai perdu des heures à chasser un bug stupide du style
std::string bad='x'+"yz"; // donne tout sauf "xyz"
("yz" était en fait le résultat d'une conversion genre class::operator
char*() ...)

Existe-t-il une combine pour empêcher C++ de compiler des bêtises à la C ?

J'ai essayé de définir un operator+(const char lhs, const char* rhs) qui
râlerait, mais VC 7.1 dit qu'une des deux opérandes doit être une classe...
--
Philippe Guglielmetti - www.dynabits.com

10 réponses

1 2 3 4 5
Avatar
Alni
Bonjour,


J'ai perdu des heures à chasser un bug stupide du style
std::string bad='x'+"yz"; // donne tout sauf "xyz"


'x' n'est pas une string. Tu ne peux pas l'additionner avec "yz" pour le
mettre dans une std::string. C'est un char, soit une valeur comprise
entre 0 et 255. Au mieux il sera peut être interprété par le compilo
comme étant la string à l'adresse 0x120.

Il faut écrire
std::string bad="x"+"yz";

Pour obtenir "xyz"

Avatar
Christophe de VIENNE
Bonjour,


J'ai perdu des heures à chasser un bug stupide du style
std::string bad='x'+"yz"; // donne tout sauf "xyz"



'x' n'est pas une string. Tu ne peux pas l'additionner avec "yz" pour le


"x" non plus, c'est un char[2]

mettre dans une std::string. C'est un char, soit une valeur comprise
entre 0 et 255. Au mieux il sera peut être interprété par le compilo
comme étant la string à l'adresse 0x120.

Il faut écrire
std::string bad="x"+"yz";

Pour obtenir "xyz"


Non, là tu additionnes des pointeurs. Si tu veux que l'opérateur + de
std::string soit utilisé et obtenir une concaténation, il faut écrire :

std::string bad = std::string("x") + "yz";

A+

Christophe

--
Christophe de Vienne


Avatar
Fabien LE LEZ
On Thu, 19 Aug 2004 18:06:23 +0200, "Alni" :

'x' n'est pas une string.


Il s'en doute. Mais justement, le problème est de forcer le compilo à
râler dans de tels cas.

Tu ne peux pas l'additionner avec "yz" pour le
mettre dans une std::string. C'est un char, soit une valeur comprise
entre 0 et 255. Au mieux il sera peut être interprété par le compilo
comme étant la string à l'adresse 0x120.


Non. 'x'+"yz" est ici égal à "xy"+'x', soit "xy"+0x78 -- 120
caractères après le début de la chaîne. Ce qui n'est bien sûr pas
valide, en plus de ne pas donner le résultat escompté ;-)

Il faut écrire
std::string bad="x"+"yz";


Ça marche, ça, tu crois ? ;-)


--
;-)

Avatar
Fabien LE LEZ
On Thu, 19 Aug 2004 18:17:25 +0200, "Jean-Noël Mégoz"
:

Ça m'étonne, d'ailleurs, qu'une telle
instruction ne provoque pas au moins un warning...


Ben oui, pointeur+entier, c'est la même chose que pointeur[entier], ou
entier[pointeur], ou entier+pointeur.


--
;-)

Avatar
Jean-Noël Mégoz
"Alni" a écrit dans le message de
news:cg2j5u$ukj$
Bonjour,


J'ai perdu des heures à chasser un bug stupide du style
std::string bad='x'+"yz"; // donne tout sauf "xyz"


'x' n'est pas une string. Tu ne peux pas l'additionner avec "yz" pour le
mettre dans une std::string. C'est un char, soit une valeur comprise
entre 0 et 255. Au mieux il sera peut être interprété par le compilo
comme étant la string à l'adresse 0x120.

Il faut écrire
std::string bad="x"+"yz";

Pour obtenir "xyz"

L'auteur du post initial le sait bien ! Ce qu'il demande, c'est s'il y a

moyen que le compilo détecte ce genre de bug.
Pour ma part, je n'en sais rien ! Ça m'étonne, d'ailleurs, qu'une telle
instruction ne provoque pas au moins un warning...


Avatar
Fabien LE LEZ
On Thu, 19 Aug 2004 18:14:49 +0200, Christophe de VIENNE
:

std::string bad = std::string("x") + "yz";


En fait, non : il faut écrire

std::string good= std::string("x") + "yz";

puisque cette fois, ça marche.


--
;-)

Avatar
Fabien LE LEZ
On Thu, 19 Aug 2004 15:05:13 +0200, "Philippe Guglielmetti"
:

Existe-t-il une combine pour empêcher C++ de compiler des bêtises à la C ?


A priori, non. Mais il n'est pas impossible que certains compilos
génèrent un warning (modulo l'option qui va bien).


--
;-)

Avatar
Alni
Bonjour,



L'auteur du post initial le sait bien ! Ce qu'il demande, c'est s'il
y a moyen que le compilo détecte ce genre de bug.
OK...pas compris...


Pour ma part, je n'en sais rien ! Ça m'étonne, d'ailleurs, qu'une
telle instruction ne provoque pas au moins un warning...


Mouais, effectivement, je viens de tester en VC++ 6, pas de warning.
Même pas un assert à l'execution.

Avatar
drkm
"Alni" writes:


J'ai perdu des heures à chasser un bug stupide du style
std::string bad='x'+"yz"; // donne tout sauf "xyz"


'x' n'est pas une string. Tu ne peux pas l'additionner avec "yz" pour
le mettre dans une std::string. C'est un char, soit une valeur
comprise entre 0 et 255. Au mieux il sera peut être interprété par le
compilo comme étant la string à l'adresse 0x120.


Si je ne me trompe pas, le résultat est un char const *, pointant à
l'adresse de "yz" augmentée de la valeur entière 'x'.

Il faut écrire
std::string bad="x"+"yz";


Non.

Pour obtenir "xyz"


Non, ni pour obtenir "xyz", ni pour rien, d'ailleurs.

~> cat fclcxx.cc
#include <iostream>
#include <ostream>
#include <string>

int main() {
std::string s = "x" + "yz" ;

std::cout
<< s
<< std::endl ;
}

~> g++ -o fclcxx fclcxx.cc -Wall -ansi -pedantic
fclcxx.cc: In function `int main()':
fclcxx.cc:5: error: invalid operands of types `const char[2]' and
`const char[3]' to binary `operator+'

~> cat fclcxx.cc
#include <iostream>
#include <ostream>
#include <string>

int main() {
std::string s1 = std::string( "x" ) + "yz" ;
std::string s2( "x" ) ;
s2 += "yz" ;

std::cout
<< s1
<< std::endl
<< s2
<< std::endl ;
}

~> g++ -o fclcxx fclcxx.cc -Wall -ansi -pedantic

~> ./fclcxx
xyz
xyz

--drkm, en recherche d'un stage : http://www.fgeorges.org/ipl/stage.html


Avatar
Falk Tannhäuser
Fabien LE LEZ wrote:

Existe-t-il une combine pour empêcher C++ de compiler des bêtises à la C ?


A priori, non. Mais il n'est pas impossible que certains compilos
génèrent un warning (modulo l'option qui va bien).


Avec 'gcc -Wall', j'ai bien un warning "array subscript has type `char'"
quand je fais
std::string bad = &'x'["yz"];
(qui est fonctionellement équivalent à
std::string bad = 'x' + "yz";
mais il me ne semble pas avoir de moyen pour faire générer un
warning dans ce cas)

Ce sont les joies de l'arithmétique des pointeurs combiné aux
règles loufoques de conversion tableau => pointeur, qui font
que le code en question *doit* être accepté par le compilateur,
bien qu'il produise un comportement indéfini.

Falk


1 2 3 4 5