C'est certes du C, mais je
voulais demander des points de vue sur le compilateur C++.
C'est certes du C, mais je
voulais demander des points de vue sur le compilateur C++.
C'est certes du C, mais je
voulais demander des points de vue sur le compilateur C++.
"Jean-Marc Bourguet" a écrit dans le message news:"Seb" writes:sprintf(c, "%s%s", c, c);
Le résultat est assez stupéfiant.
Et tu t'attendais a quoi en ecrivant ce genre de choses?
(au fait, si tu fais du c, il y a fr.comp.lang.c)
A+
C'était juste un test. Je m'attendais au même résultat que génère le
compilateur IBM que j'utilise sous unix ;-) C'est certes du C, mais je
voulais demander des points de vue sur le compilateur C++.
"Jean-Marc Bourguet" <jm@bourguet.org> a écrit dans le message news:
pxbk76w5892.fsf@news.bourguet.org
"Seb" <sebastien_nospam@yahoo.com> writes:
sprintf(c, "%s%s", c, c);
Le résultat est assez stupéfiant.
Et tu t'attendais a quoi en ecrivant ce genre de choses?
(au fait, si tu fais du c, il y a fr.comp.lang.c)
A+
C'était juste un test. Je m'attendais au même résultat que génère le
compilateur IBM que j'utilise sous unix ;-) C'est certes du C, mais je
voulais demander des points de vue sur le compilateur C++.
"Jean-Marc Bourguet" a écrit dans le message news:"Seb" writes:sprintf(c, "%s%s", c, c);
Le résultat est assez stupéfiant.
Et tu t'attendais a quoi en ecrivant ce genre de choses?
(au fait, si tu fais du c, il y a fr.comp.lang.c)
A+
C'était juste un test. Je m'attendais au même résultat que génère le
compilateur IBM que j'utilise sous unix ;-) C'est certes du C, mais je
voulais demander des points de vue sur le compilateur C++.
Seb wrote:"Fabien SK" <fabsk+ a écrit dans le message news:
3f97e687$0$10409$printf("before = %sn", c);
sprintf(d, "%s%s", c, c);
sprintf(c, "%s%s", c, c);
printf("after (x) = %sn", d);
printf("after = %sn", c);
sprintf(c, "%s%s", c, c);
Pas bon ! Tu écris dans un buffer dans lequel tu lis en même temps.
Le hic c'est que d'autres compilateurs réussissent ce test.
J'ai écrit ce programme. Il marche avec Visual C++ 6. Marchera-t-il avec
ton compilateur ?
#include <iostream>
int main(int argc, char *argv[])
{
int toto = 0;
*reinterpret_cast<int*>(0x0012FF7C) = 5;
std::cout << toto << std::endl;
return 0;
}
Seb wrote:
"Fabien SK" <fabsk+news@free.fr> a écrit dans le message news:
3f97e687$0$10409$626a54ce@news.free.fr
printf("before = %sn", c);
sprintf(d, "%s%s", c, c);
sprintf(c, "%s%s", c, c);
printf("after (x) = %sn", d);
printf("after = %sn", c);
sprintf(c, "%s%s", c, c);
Pas bon ! Tu écris dans un buffer dans lequel tu lis en même temps.
Le hic c'est que d'autres compilateurs réussissent ce test.
J'ai écrit ce programme. Il marche avec Visual C++ 6. Marchera-t-il avec
ton compilateur ?
#include <iostream>
int main(int argc, char *argv[])
{
int toto = 0;
*reinterpret_cast<int*>(0x0012FF7C) = 5;
std::cout << toto << std::endl;
return 0;
}
Seb wrote:"Fabien SK" <fabsk+ a écrit dans le message news:
3f97e687$0$10409$printf("before = %sn", c);
sprintf(d, "%s%s", c, c);
sprintf(c, "%s%s", c, c);
printf("after (x) = %sn", d);
printf("after = %sn", c);
sprintf(c, "%s%s", c, c);
Pas bon ! Tu écris dans un buffer dans lequel tu lis en même temps.
Le hic c'est que d'autres compilateurs réussissent ce test.
J'ai écrit ce programme. Il marche avec Visual C++ 6. Marchera-t-il avec
ton compilateur ?
#include <iostream>
int main(int argc, char *argv[])
{
int toto = 0;
*reinterpret_cast<int*>(0x0012FF7C) = 5;
std::cout << toto << std::endl;
return 0;
}
On Thu, 23 Oct 2003 16:50:29 +0200, "Seb"
wrote:C'est certes du C, mais je
voulais demander des points de vue sur le compilateur C++.
Bah oui, mais j'imagine qu'aucun lecteur de ce forum n'a écrit un tel
code, du moins pas ces dernières années...
De toutes façons, tout résultat est conforme à la norme -- y compris
un plantage.
On Thu, 23 Oct 2003 16:50:29 +0200, "Seb" <sebastien_nospam@yahoo.com>
wrote:
C'est certes du C, mais je
voulais demander des points de vue sur le compilateur C++.
Bah oui, mais j'imagine qu'aucun lecteur de ce forum n'a écrit un tel
code, du moins pas ces dernières années...
De toutes façons, tout résultat est conforme à la norme -- y compris
un plantage.
On Thu, 23 Oct 2003 16:50:29 +0200, "Seb"
wrote:C'est certes du C, mais je
voulais demander des points de vue sur le compilateur C++.
Bah oui, mais j'imagine qu'aucun lecteur de ce forum n'a écrit un tel
code, du moins pas ces dernières années...
De toutes façons, tout résultat est conforme à la norme -- y compris
un plantage.
Bah oui, mais j'imagine qu'aucun lecteur de ce forum n'a écrit un tel
code, du moins pas ces dernières années...
De toutes façons, tout résultat est conforme à la norme -- y compris
un plantage.
Et bien si à partir d'un nom tu dois générer un fichier qui est dans
"NOM/NOM" : j'aurais aimé que mon sprintf(c, "%s/%s", c, c);
fonctionne. Mon résultat est "/".
Bah oui, mais j'imagine qu'aucun lecteur de ce forum n'a écrit un tel
code, du moins pas ces dernières années...
De toutes façons, tout résultat est conforme à la norme -- y compris
un plantage.
Et bien si à partir d'un nom tu dois générer un fichier qui est dans
"NOM/NOM" : j'aurais aimé que mon sprintf(c, "%s/%s", c, c);
fonctionne. Mon résultat est "/".
Bah oui, mais j'imagine qu'aucun lecteur de ce forum n'a écrit un tel
code, du moins pas ces dernières années...
De toutes façons, tout résultat est conforme à la norme -- y compris
un plantage.
Et bien si à partir d'un nom tu dois générer un fichier qui est dans
"NOM/NOM" : j'aurais aimé que mon sprintf(c, "%s/%s", c, c);
fonctionne. Mon résultat est "/".
"Seb" a écrit dans le message de
news:bn8pvt$orn$"Fabien SK" <fabsk+ a écrit dans le message news:
3f97e687$0$10409$printf("before = %sn", c);
sprintf(d, "%s%s", c, c);
sprintf(c, "%s%s", c, c);
printf("after (x) = %sn", d);
printf("after = %sn", c);
sprintf(c, "%s%s", c, c);
Pas bon ! Tu écris dans un buffer dans lequel tu lis en même temps.
Le hic c'est que d'autres compilateurs réussissent ce test.
Ca veut dire quoi "réussissent" ?
Les compilateurs Sun et Compaq donnent comme résultat "totototo" alors
que le compilateur HP donne ""...
Quel est le comportement attendu ?
Je ne pense pas que la Norme C le définisse.
"Seb" <sebastien_nospam@yahoo.com> a écrit dans le message de
news:bn8pvt$orn$1@s1.read.news.oleane.net...
"Fabien SK" <fabsk+news@free.fr> a écrit dans le message news:
3f97e687$0$10409$626a54ce@news.free.fr
printf("before = %sn", c);
sprintf(d, "%s%s", c, c);
sprintf(c, "%s%s", c, c);
printf("after (x) = %sn", d);
printf("after = %sn", c);
sprintf(c, "%s%s", c, c);
Pas bon ! Tu écris dans un buffer dans lequel tu lis en même temps.
Le hic c'est que d'autres compilateurs réussissent ce test.
Ca veut dire quoi "réussissent" ?
Les compilateurs Sun et Compaq donnent comme résultat "totototo" alors
que le compilateur HP donne ""...
Quel est le comportement attendu ?
Je ne pense pas que la Norme C le définisse.
"Seb" a écrit dans le message de
news:bn8pvt$orn$"Fabien SK" <fabsk+ a écrit dans le message news:
3f97e687$0$10409$printf("before = %sn", c);
sprintf(d, "%s%s", c, c);
sprintf(c, "%s%s", c, c);
printf("after (x) = %sn", d);
printf("after = %sn", c);
sprintf(c, "%s%s", c, c);
Pas bon ! Tu écris dans un buffer dans lequel tu lis en même temps.
Le hic c'est que d'autres compilateurs réussissent ce test.
Ca veut dire quoi "réussissent" ?
Les compilateurs Sun et Compaq donnent comme résultat "totototo" alors
que le compilateur HP donne ""...
Quel est le comportement attendu ?
Je ne pense pas que la Norme C le définisse.
"Rémy" wrote in message
news:<bn8rq8$pvm$..."Seb" a écrit dans le message de
news:bn8pvt$orn$"Fabien SK" <fabsk+ a écrit dans le message news:
3f97e687$0$10409$printf("before = %sn", c);
sprintf(d, "%s%s", c, c);
sprintf(c, "%s%s", c, c);
printf("after (x) = %sn", d);
printf("after = %sn", c);
sprintf(c, "%s%s", c, c);
Pas bon ! Tu écris dans un buffer dans lequel tu lis en même temps.
Le hic c'est que d'autres compilateurs réussissent ce test.
Ca veut dire quoi "réussissent" ?
Les compilateurs Sun et Compaq donnent comme résultat "totototo"
alors que le compilateur HP donne ""...
Quel est le comportement attendu ?
Je ne pense pas que la Norme C le définisse.
En C99, c'est un comportement indéfini, parce que le premier paramètre
de sprintf a le type « char * restrict ».
Mais c'est la norme C++ qui l'intéresse, donc C90. Je n'en a
malheureusement pas une copie ici pour vérifier, mais c'est toute à
fait possible qu'elle le permet. Par inadvertance, probablement, si
c'est le cas, mais peut-être quand même.
Mais enfin, vue qu'il s'agit d'un compilateur C++, pourquoi pas écrire
simplement :
std::string c( "toto" ) ;
std::ostringstream tmp ;
tmp << c << c ;
c = tmp.str() ;
Là, on est sûr que ça marche.
"Rémy" <remy.bertrand@cgeyt.com> wrote in message
news:<bn8rq8$pvm$1@s1.read.news.oleane.net>...
"Seb" <sebastien_nospam@yahoo.com> a écrit dans le message de
news:bn8pvt$orn$1@s1.read.news.oleane.net...
"Fabien SK" <fabsk+news@free.fr> a écrit dans le message news:
3f97e687$0$10409$626a54ce@news.free.fr
printf("before = %sn", c);
sprintf(d, "%s%s", c, c);
sprintf(c, "%s%s", c, c);
printf("after (x) = %sn", d);
printf("after = %sn", c);
sprintf(c, "%s%s", c, c);
Pas bon ! Tu écris dans un buffer dans lequel tu lis en même temps.
Le hic c'est que d'autres compilateurs réussissent ce test.
Ca veut dire quoi "réussissent" ?
Les compilateurs Sun et Compaq donnent comme résultat "totototo"
alors que le compilateur HP donne ""...
Quel est le comportement attendu ?
Je ne pense pas que la Norme C le définisse.
En C99, c'est un comportement indéfini, parce que le premier paramètre
de sprintf a le type « char * restrict ».
Mais c'est la norme C++ qui l'intéresse, donc C90. Je n'en a
malheureusement pas une copie ici pour vérifier, mais c'est toute à
fait possible qu'elle le permet. Par inadvertance, probablement, si
c'est le cas, mais peut-être quand même.
Mais enfin, vue qu'il s'agit d'un compilateur C++, pourquoi pas écrire
simplement :
std::string c( "toto" ) ;
std::ostringstream tmp ;
tmp << c << c ;
c = tmp.str() ;
Là, on est sûr que ça marche.
"Rémy" wrote in message
news:<bn8rq8$pvm$..."Seb" a écrit dans le message de
news:bn8pvt$orn$"Fabien SK" <fabsk+ a écrit dans le message news:
3f97e687$0$10409$printf("before = %sn", c);
sprintf(d, "%s%s", c, c);
sprintf(c, "%s%s", c, c);
printf("after (x) = %sn", d);
printf("after = %sn", c);
sprintf(c, "%s%s", c, c);
Pas bon ! Tu écris dans un buffer dans lequel tu lis en même temps.
Le hic c'est que d'autres compilateurs réussissent ce test.
Ca veut dire quoi "réussissent" ?
Les compilateurs Sun et Compaq donnent comme résultat "totototo"
alors que le compilateur HP donne ""...
Quel est le comportement attendu ?
Je ne pense pas que la Norme C le définisse.
En C99, c'est un comportement indéfini, parce que le premier paramètre
de sprintf a le type « char * restrict ».
Mais c'est la norme C++ qui l'intéresse, donc C90. Je n'en a
malheureusement pas une copie ici pour vérifier, mais c'est toute à
fait possible qu'elle le permet. Par inadvertance, probablement, si
c'est le cas, mais peut-être quand même.
Mais enfin, vue qu'il s'agit d'un compilateur C++, pourquoi pas écrire
simplement :
std::string c( "toto" ) ;
std::ostringstream tmp ;
tmp << c << c ;
c = tmp.str() ;
Là, on est sûr que ça marche.
Bah oui, mais j'imagine qu'aucun lecteur de ce forum n'a écrit un
tel code, du moins pas ces dernières années...
De toutes façons, tout résultat est conforme à la norme -- y compris
un plantage.
Et bien si à partir d'un nom tu dois générer un fichier qui est dans
"NOM/NOM" : j'aurais aimé que mon sprintf(c, "%s/%s", c, c);
fonctionne. Mon résultat est "/".
Apparement tu as du mal avec la notion de "non défini". En général
c'est bettement du au fait que préciser ce que ca doit faire
obligerait l'implémentation a faire des choses spécifiques pour gérer
le problème en question.
Il y a une page qui parle des problèmes d'écrasement dans les
différentes fonctions de la lib C:
http://wwwwbs.cs.tu-berlin.de/user-taipan/kraxel/gnuinfo/libc/Formatted_Outp
A propos de sprintf on y lit:
"The behavior of this function is undefined if copying takes place
between objects that overlap---for example, if s is also given as an
argument to be printed under control of the `%s' conversion."
Accessoirement, tu critiques le compilateur, mais le pauvre n'y ai
pour rien là dedans, c'est dans la librairie que ca se passe.
Le problème dans ce que tu voudrais, c'est qu'il faudrait faire des
copies temporaires dans des buffers pour que tout ce passe bien, avec
ce que cela implique en problèmes divers au niveau de la taille à
allouer...
Vu que sprintf c'est un peu compliqué, on va plutôt parler de strcat.
Au '/' près, ce que tu voulais faire c'est l'équivalent de ca:
//------------------------
char c[100] = "toto";
strcat(c,c);
//------------------------
Vu que "c" vaux "toto", tu imagines normalement que concaténer C à C
va donner "totototo", exactement de la même façon qu'en BASIC
C$=C$+C$ va bien effectivement donner ce que tu recherches...
Si je vais chercher dans les sources de la lib C standard de VC6, je
trouve ca:
//------------------------
char * __cdecl strcat (
char * dst,
const char * src
)
{
char * cp = dst;
while( *cp )
cp++; /* find end of dst */
while( *cp++ = *src++ ) ; /* Copy src to end of dst */
return( dst ); /* return dst */
}
//------------------------
On a "c" qui vaut ca: toto0?????????????????
[0 => octet null / ? => octet alloué dans ton buffer / ! => octet pas
dans le buffer]
Si on passe "c" en paramètre, on a donc "cp=dst=c" et "src=c".
src => toto0????????????
cp => toto0????????????
dst => toto0????????????
Ensuite on recherche la fin de la destination, quand on à trouvé on à
ca:
src => toto0????????????
cp => 0??????????????
dst => toto0????????????
Et maintenant on copie de "src" vers "cp" jusqu'a ce qu'on ai lu un
zéro...
Itération 1:
*dst = *src (on écrit un 't')
src++
dst++
résultat fin d'itération:
src => otot????????????
cp => ??????????????
dst => totot????????????
Itération 2:
*dst = *src (on écrit un 'o')
src++
dst++
résultat fin d'itération:
src => toto????????????
cp => ??????????????
dst => tototo????????????
Itération 3:
*dst = *src (on écrit un 't')
src++
dst++
résultat fin d'itération:
src => otot????????????
cp => ??????????????
dst => tototot????????????
Itération 96:
*dst = *src (on écrit un 't')
src++
dst++
résultat fin d'itération:
src => otot!!!!
cp => ?!!!!!!!!!!!!!!!!!!!!!!
dst => totototototototototototototot...ototototototototo
En gros, à la première itération tu as explosé le '0' terminant la
chaine 'toto', donc la condition pour terminer la copie à disparu, et
ca continue très longtemps comme ca, jusqu'a ce qu'on tombe (par
hasard) sur un '0' qui traine en mémoire, ou jusqu'a ce que tu
commence à tapper en dehors de la mémoire autorisée pour ton
programme et là il se produit des choses plus ou moins dépendantes de
ton systeme...
Il serait possible de faire un strcat qui n'ai pas se problème, mais
il serait monstrueusement plus lent parce qu'il faudrait parcourir la
chaine source pour trouver sa longueur et après utiliser ca comme
compteur lors de la recopie.
Mike
Bah oui, mais j'imagine qu'aucun lecteur de ce forum n'a écrit un
tel code, du moins pas ces dernières années...
De toutes façons, tout résultat est conforme à la norme -- y compris
un plantage.
Et bien si à partir d'un nom tu dois générer un fichier qui est dans
"NOM/NOM" : j'aurais aimé que mon sprintf(c, "%s/%s", c, c);
fonctionne. Mon résultat est "/".
Apparement tu as du mal avec la notion de "non défini". En général
c'est bettement du au fait que préciser ce que ca doit faire
obligerait l'implémentation a faire des choses spécifiques pour gérer
le problème en question.
Il y a une page qui parle des problèmes d'écrasement dans les
différentes fonctions de la lib C:
http://wwwwbs.cs.tu-berlin.de/user-taipan/kraxel/gnuinfo/libc/Formatted_Outp
A propos de sprintf on y lit:
"The behavior of this function is undefined if copying takes place
between objects that overlap---for example, if s is also given as an
argument to be printed under control of the `%s' conversion."
Accessoirement, tu critiques le compilateur, mais le pauvre n'y ai
pour rien là dedans, c'est dans la librairie que ca se passe.
Le problème dans ce que tu voudrais, c'est qu'il faudrait faire des
copies temporaires dans des buffers pour que tout ce passe bien, avec
ce que cela implique en problèmes divers au niveau de la taille à
allouer...
Vu que sprintf c'est un peu compliqué, on va plutôt parler de strcat.
Au '/' près, ce que tu voulais faire c'est l'équivalent de ca:
//------------------------
char c[100] = "toto";
strcat(c,c);
//------------------------
Vu que "c" vaux "toto", tu imagines normalement que concaténer C à C
va donner "totototo", exactement de la même façon qu'en BASIC
C$=C$+C$ va bien effectivement donner ce que tu recherches...
Si je vais chercher dans les sources de la lib C standard de VC6, je
trouve ca:
//------------------------
char * __cdecl strcat (
char * dst,
const char * src
)
{
char * cp = dst;
while( *cp )
cp++; /* find end of dst */
while( *cp++ = *src++ ) ; /* Copy src to end of dst */
return( dst ); /* return dst */
}
//------------------------
On a "c" qui vaut ca: toto0?????????????????
[0 => octet null / ? => octet alloué dans ton buffer / ! => octet pas
dans le buffer]
Si on passe "c" en paramètre, on a donc "cp=dst=c" et "src=c".
src => toto0????????????
cp => toto0????????????
dst => toto0????????????
Ensuite on recherche la fin de la destination, quand on à trouvé on à
ca:
src => toto0????????????
cp => 0??????????????
dst => toto0????????????
Et maintenant on copie de "src" vers "cp" jusqu'a ce qu'on ai lu un
zéro...
Itération 1:
*dst = *src (on écrit un 't')
src++
dst++
résultat fin d'itération:
src => otot????????????
cp => ??????????????
dst => totot????????????
Itération 2:
*dst = *src (on écrit un 'o')
src++
dst++
résultat fin d'itération:
src => toto????????????
cp => ??????????????
dst => tototo????????????
Itération 3:
*dst = *src (on écrit un 't')
src++
dst++
résultat fin d'itération:
src => otot????????????
cp => ??????????????
dst => tototot????????????
Itération 96:
*dst = *src (on écrit un 't')
src++
dst++
résultat fin d'itération:
src => otot!!!!
cp => ?!!!!!!!!!!!!!!!!!!!!!!
dst => totototototototototototototot...ototototototototo
En gros, à la première itération tu as explosé le '0' terminant la
chaine 'toto', donc la condition pour terminer la copie à disparu, et
ca continue très longtemps comme ca, jusqu'a ce qu'on tombe (par
hasard) sur un '0' qui traine en mémoire, ou jusqu'a ce que tu
commence à tapper en dehors de la mémoire autorisée pour ton
programme et là il se produit des choses plus ou moins dépendantes de
ton systeme...
Il serait possible de faire un strcat qui n'ai pas se problème, mais
il serait monstrueusement plus lent parce qu'il faudrait parcourir la
chaine source pour trouver sa longueur et après utiliser ca comme
compteur lors de la recopie.
Mike
Bah oui, mais j'imagine qu'aucun lecteur de ce forum n'a écrit un
tel code, du moins pas ces dernières années...
De toutes façons, tout résultat est conforme à la norme -- y compris
un plantage.
Et bien si à partir d'un nom tu dois générer un fichier qui est dans
"NOM/NOM" : j'aurais aimé que mon sprintf(c, "%s/%s", c, c);
fonctionne. Mon résultat est "/".
Apparement tu as du mal avec la notion de "non défini". En général
c'est bettement du au fait que préciser ce que ca doit faire
obligerait l'implémentation a faire des choses spécifiques pour gérer
le problème en question.
Il y a une page qui parle des problèmes d'écrasement dans les
différentes fonctions de la lib C:
http://wwwwbs.cs.tu-berlin.de/user-taipan/kraxel/gnuinfo/libc/Formatted_Outp
A propos de sprintf on y lit:
"The behavior of this function is undefined if copying takes place
between objects that overlap---for example, if s is also given as an
argument to be printed under control of the `%s' conversion."
Accessoirement, tu critiques le compilateur, mais le pauvre n'y ai
pour rien là dedans, c'est dans la librairie que ca se passe.
Le problème dans ce que tu voudrais, c'est qu'il faudrait faire des
copies temporaires dans des buffers pour que tout ce passe bien, avec
ce que cela implique en problèmes divers au niveau de la taille à
allouer...
Vu que sprintf c'est un peu compliqué, on va plutôt parler de strcat.
Au '/' près, ce que tu voulais faire c'est l'équivalent de ca:
//------------------------
char c[100] = "toto";
strcat(c,c);
//------------------------
Vu que "c" vaux "toto", tu imagines normalement que concaténer C à C
va donner "totototo", exactement de la même façon qu'en BASIC
C$=C$+C$ va bien effectivement donner ce que tu recherches...
Si je vais chercher dans les sources de la lib C standard de VC6, je
trouve ca:
//------------------------
char * __cdecl strcat (
char * dst,
const char * src
)
{
char * cp = dst;
while( *cp )
cp++; /* find end of dst */
while( *cp++ = *src++ ) ; /* Copy src to end of dst */
return( dst ); /* return dst */
}
//------------------------
On a "c" qui vaut ca: toto0?????????????????
[0 => octet null / ? => octet alloué dans ton buffer / ! => octet pas
dans le buffer]
Si on passe "c" en paramètre, on a donc "cp=dst=c" et "src=c".
src => toto0????????????
cp => toto0????????????
dst => toto0????????????
Ensuite on recherche la fin de la destination, quand on à trouvé on à
ca:
src => toto0????????????
cp => 0??????????????
dst => toto0????????????
Et maintenant on copie de "src" vers "cp" jusqu'a ce qu'on ai lu un
zéro...
Itération 1:
*dst = *src (on écrit un 't')
src++
dst++
résultat fin d'itération:
src => otot????????????
cp => ??????????????
dst => totot????????????
Itération 2:
*dst = *src (on écrit un 'o')
src++
dst++
résultat fin d'itération:
src => toto????????????
cp => ??????????????
dst => tototo????????????
Itération 3:
*dst = *src (on écrit un 't')
src++
dst++
résultat fin d'itération:
src => otot????????????
cp => ??????????????
dst => tototot????????????
Itération 96:
*dst = *src (on écrit un 't')
src++
dst++
résultat fin d'itération:
src => otot!!!!
cp => ?!!!!!!!!!!!!!!!!!!!!!!
dst => totototototototototototototot...ototototototototo
En gros, à la première itération tu as explosé le '0' terminant la
chaine 'toto', donc la condition pour terminer la copie à disparu, et
ca continue très longtemps comme ca, jusqu'a ce qu'on tombe (par
hasard) sur un '0' qui traine en mémoire, ou jusqu'a ce que tu
commence à tapper en dehors de la mémoire autorisée pour ton
programme et là il se produit des choses plus ou moins dépendantes de
ton systeme...
Il serait possible de faire un strcat qui n'ai pas se problème, mais
il serait monstrueusement plus lent parce qu'il faudrait parcourir la
chaine source pour trouver sa longueur et après utiliser ca comme
compteur lors de la recopie.
Mike
Et bien si à partir d'un nom tu dois générer un fichier qui est dans
"NOM/NOM" : j'aurais aimé que mon sprintf(c, "%s/%s", c, c); fonctionne.
Mon résultat est "/".
Disons que la lib met les aérofreins, ce qui n'est pas plus idiot. Notez que
Et bien si à partir d'un nom tu dois générer un fichier qui est dans
"NOM/NOM" : j'aurais aimé que mon sprintf(c, "%s/%s", c, c); fonctionne.
Mon résultat est "/".
Disons que la lib met les aérofreins, ce qui n'est pas plus idiot. Notez que
Et bien si à partir d'un nom tu dois générer un fichier qui est dans
"NOM/NOM" : j'aurais aimé que mon sprintf(c, "%s/%s", c, c); fonctionne.
Mon résultat est "/".
Disons que la lib met les aérofreins, ce qui n'est pas plus idiot. Notez que
"Fabien SK" <fabsk+ a écrit dans le message news:
3f97f635$0$10401$Seb wrote:"Fabien SK" <fabsk+ a écrit dans le message news:
3f97e687$0$10409$printf("before = %sn", c);
sprintf(d, "%s%s", c, c);
sprintf(c, "%s%s", c, c);
printf("after (x) = %sn", d);
printf("after = %sn", c);
sprintf(c, "%s%s", c, c);
Pas bon ! Tu écris dans un buffer dans lequel tu lis en même temps.
Le hic c'est que d'autres compilateurs réussissent ce test.
J'ai écrit ce programme. Il marche avec Visual C++ 6. Marchera-t-il avec
ton compilateur ?
#include <iostream>
int main(int argc, char *argv[])
{
int toto = 0;
*reinterpret_cast<int*>(0x0012FF7C) = 5;
std::cout << toto << std::endl;
return 0;
}
Il affiche 0 avec Borland C++ 55
"Fabien SK" <fabsk+news@free.fr> a écrit dans le message news:
3f97f635$0$10401$626a54ce@news.free.fr...
Seb wrote:
"Fabien SK" <fabsk+news@free.fr> a écrit dans le message news:
3f97e687$0$10409$626a54ce@news.free.fr
printf("before = %sn", c);
sprintf(d, "%s%s", c, c);
sprintf(c, "%s%s", c, c);
printf("after (x) = %sn", d);
printf("after = %sn", c);
sprintf(c, "%s%s", c, c);
Pas bon ! Tu écris dans un buffer dans lequel tu lis en même temps.
Le hic c'est que d'autres compilateurs réussissent ce test.
J'ai écrit ce programme. Il marche avec Visual C++ 6. Marchera-t-il avec
ton compilateur ?
#include <iostream>
int main(int argc, char *argv[])
{
int toto = 0;
*reinterpret_cast<int*>(0x0012FF7C) = 5;
std::cout << toto << std::endl;
return 0;
}
Il affiche 0 avec Borland C++ 55
"Fabien SK" <fabsk+ a écrit dans le message news:
3f97f635$0$10401$Seb wrote:"Fabien SK" <fabsk+ a écrit dans le message news:
3f97e687$0$10409$printf("before = %sn", c);
sprintf(d, "%s%s", c, c);
sprintf(c, "%s%s", c, c);
printf("after (x) = %sn", d);
printf("after = %sn", c);
sprintf(c, "%s%s", c, c);
Pas bon ! Tu écris dans un buffer dans lequel tu lis en même temps.
Le hic c'est que d'autres compilateurs réussissent ce test.
J'ai écrit ce programme. Il marche avec Visual C++ 6. Marchera-t-il avec
ton compilateur ?
#include <iostream>
int main(int argc, char *argv[])
{
int toto = 0;
*reinterpret_cast<int*>(0x0012FF7C) = 5;
std::cout << toto << std::endl;
return 0;
}
Il affiche 0 avec Borland C++ 55