question en C - C - Programmation
Marsh Posté le 17-12-2003 à 14:45:20
non.
const char *str = "phrase1";
fait pointer str vers une chaine allouée statiquement. l'écriture sur cette zone est un comportement indéfini, donc pas touche
Marsh Posté le 17-12-2003 à 14:46:41
si tu affecte par la suite un nom plus grand ça va joliment planter
[edit] : pire que luky luke le taz
Marsh Posté le 17-12-2003 à 14:47:43
donc faire
int main()
{
char *str="prhase1";
printf(str);
}
est incorect?
(je sais que dans ce cas faire printf("phrase1" ) est plus rapide mais cest juste la declaration ou je minteroge
sinon pourait tu etre plus precis?
dans le cas ou je ne veut PAS editer la chaine de caractere?
il vaut mieux faire un malloc?
Marsh Posté le 17-12-2003 à 15:16:45
"phrase1" est un chaine littérale, stockée en dur dans ton exe (ouvre ton exe avec notepad tu vas la trouver), dans une section de code initialisé généralement en lecture seule. La modifier est donc interdit et fait planter ton prog. C'est pour cela qu'il est préférable de mettre const.
De manire générale, si tu ne veux pas modifier une chaine, ben on met const, c'est mieux.
Par contre ce que je pige pas c'est pourquoi main c'est
Code :
|
et pas
Code :
|
Marsh Posté le 17-12-2003 à 17:59:03
parce que c''est canonique, des histoires de spécifications à la con qu'on doit pas changer ce qui a été fait auparavant
Marsh Posté le 17-12-2003 à 18:46:06
tgaudlol a écrit : donc faire |
Non, le malloc va allouer ta chaine en mémoire, elle sera parfaitement modifiable, donc si tu ne comptes pas la modifier tu peux faire :
Code :
|
Marsh Posté le 17-12-2003 à 18:48:36
harrysauce a écrit :
|
Code :
|
Aussi, non ?
Marsh Posté le 17-12-2003 à 18:51:24
R3g a écrit :
|
Faut vraiment avoir envie de s'emmerder
Marsh Posté le 17-12-2003 à 19:01:02
harrysauce a écrit : Faut vraiment avoir envie de s'emmerder |
comme tu dis, si on aime les trucs qui compilent pas...
le const ici, il sert à rien.
Note : pour le développement de Linux, on encourage quand même cela, un tableua, plutot qu'un pointeur -> pointeur = pointeur + mémoire lecture seule (allouée pour toute la durée de l'exécution), tableau = on gagne la taille du pointeur ( ) et on encombre pas ad vitam eternam le dit segment.
Marsh Posté le 17-12-2003 à 22:03:47
euh lorsque je fais, char *str = "fille"; et lorsque je fais const char *str = "fille"; mon compilo sort exactement la meme chose
a noter que j'ai un warning lorsque je met le "const"
Marsh Posté le 17-12-2003 à 22:06:20
t'as le warnings quand tu ne le mets pas. ton compilo génère la meme chose oui, le const est là pour lui dire de gueuler si tu tentes de modifier str[i]
Marsh Posté le 17-12-2003 à 22:16:16
ben t'as un compilateur de merde et complètement obsolète. c'est quoi le warning et ton compilo pour savoir?
Marsh Posté le 18-12-2003 à 03:55:34
tgaudlol a écrit : mettre |
Chaînes littérales de caractère
À l'origine de C, les chaînes littérales de caractères étaient des tableaux statiques anonymes de caractères, initialisés avec les caractères. Lors de la standardisation de C, le mot clé const a été introduit et les chaînes littérales ont été rendues constantes pour pouvoir être partagées ou mises en mémoire morte. Il aurait donc été logique de donner aux chaînes littérales le type « tableau de caractères constants.» Cependant l'usage suivant était extrêmement répandu :
char t[] = "hello";
char * p = "hello";
Or cet usage aurait causé un avertissement du compilateur à cause de la conversion de const char[] en char[]. Dans le standard ANSI C, les chaînes littérales gardent donc le type char[], bien qu'elles soient considérées constantes.
(piqué en bas de cette page: http://home.infomaniak.ch/mongenet [...] /hist.html )
Donc, en resumé:
ces chaines sont constantes, mais pour garder la compatibilité avec l'existant, on ne met pas le modificateur const.
Donc on ne peut pas modifier la chaine.
Par contre, comme il n'y a pas de modificateur const, on peut dereferencer le pointeur et le faire pointer sur une autre chaine quelconque.
Taz a raison: pour tout ce qui est du code neuf, il faut employer const:
const char t[] = "hello";
const char * p = "hello";
car on n'a pas les problemes de compatibilité, puisque c'est du code neuf.
Notes: le compilo VC 6 de Microsoft est particulierement buggé a ce sujet.
char * p = "toto";
p[2] = 'b';
ne le gene pas, mais ce qui est grave, c'est que la chaine "toto" en principe constante, est modifiée, comme le montre l'essai avec ceci:
char * p = "toto";
char * q = "toto";
p[2] = 'b';
p et q sont modifiees!!! En effet, le compilo trouvant deux chaines constantes identiques, a fait pointer les deux pointeurs sur la meme zone memoire, en principe non modifiable.
L'effet de bord sur q peut conduire a des bugs particulierement vicieux a elucider.
Le support du mot cle const en C par le compilo VC 6 est loin d'etre tres bon, mais au moins, il interdit la modification:
const char * p = "toto";
p[2] = 'b';
ne passe pas.
A+,
Marsh Posté le 18-12-2003 à 12:02:36
Un petit up pour que chacun lise le bug du compilo Visual C 6 que je relate dans mon post precedent (mis a 4h du mat, pas l'heure la plus lue...)
A+,
Marsh Posté le 18-12-2003 à 12:21:13
Harkonnen a écrit : énorme ce bug quand meme |
un bug non-corrigé n'en est plus un, c'est un défaut.
Ah j'oubliais, « acheter la nouvelle version »
Marsh Posté le 18-12-2003 à 12:34:02
Taz a écrit : un bug non-corrigé n'en est plus un, c'est un défaut. |
A l'iut lors d'une démo sous Visual Studio .NET le prof a trouvé un bug encore plus énorme.
Il avait écrit un truc du genre :
Code :
|
Et ben ca passe à la compil!
En fait VS.NET créé le i du for dans le registre, et l'autre i dans le tas.....
Marsh Posté le 18-12-2003 à 12:37:48
Taz a écrit : quelqu'un pour lui expliquer siouplait |
de quoi?
que c'est pas du C mais du C++?
ca va je sais, mais vu que vous parliez des bugs de visual c++.....
Après si mon post est faux, je m'en excuse, mais si je me souviens bien, c'était ca.....
Marsh Posté le 18-12-2003 à 12:39:05
Taz a écrit : quelqu'un pour lui expliquer siouplait |
Nan c'est a toi qu'on va faire un cours
en plus tu va etre content, tu va pouvoir vomir sur VC. Le prof est visiblement un habitué de VC6, et le bug du for fais parti des gros bugs connus de VC6 (sous VC6 le truc aurait beugler)
Harry :
Citation : En fait VS.NET créé le i du for dans le registre, et l'autre i dans le tas..... |
nan c'est naze comme explication ca
Marsh Posté le 18-12-2003 à 12:40:02
1) ce code est parfaitement légal en C99 et C++ et l'a toujours été. C'est VC6 qui ne le gérait pas, pour ton prof c'était le coportement standard, et là il s'étonne que du code du plus pur ISO compile ... très fort ...
2) trop forte ton explication, t'as vraiment rien compris à rien
Marsh Posté le 18-12-2003 à 12:41:22
chrisbk a écrit :
|
Oué mais c'est ce qui se passe
Marsh Posté le 18-12-2003 à 12:42:10
ReplyMarsh Posté le 18-12-2003 à 12:43:01
harrysauce a écrit : Oué mais c'est ce qui se passe |
Nan
compil en debug et ton explication se petera la gueule
Marsh Posté le 18-12-2003 à 12:44:47
Taz a écrit : 1) ce code est parfaitement légal en C99 et C++ et l'a toujours été. C'est VC6 qui ne le gérait pas, pour ton prof c'était le coportement standard, et là il s'étonne que du code du plus pur ISO compile ... très fort ... |
Super, merci, t'es pas non plus obligé de me prendre de haut
Plutot de me dire que je suis qu'une merde et que j'y connais rien à rien, explique moi depuis quand, et surtout pourquoi on peut déclarer 2 variables ayant le même nom!
Ensuite c'est pas parce que mon exemple est bidon que je comprends rien à rien, je ne fait que remettre l'exemple à partit duquel c'est parti lors de la démo....
Marsh Posté le 18-12-2003 à 12:46:01
harrysauce a écrit : Plutot de me dire que je suis qu'une merde et que j'y connais rien à rien, explique moi depuis quand, et surtout pourquoi on peut déclarer 2 variables ayant le même nom! |
depuis toujours en C et C++, pourvu qu'elles n'aient pas la même portée
Marsh Posté le 18-12-2003 à 12:46:08
chrisbk a écrit : |
Ben c'est justement en passant en debug qu'on avait vu qu'il y en avait un dans le registre et l'autre dans le tas, après comme je l'ai déjà dit, p'tet que je me suis trompé dans mon exemple, ca fait un p'tit moment qu'on l'a vu, mais il me semble que c'était ca.
Marsh Posté le 18-12-2003 à 12:46:34
harrysauce a écrit : |
question de "scope"
genre
Code :
|
illegal
par contre
Code :
|
legal
le i de la boucle est declaré a l'interieur de la boucle (et n'est donc pas visible a l'exterieur)
Marsh Posté le 18-12-2003 à 12:47:16
harrysauce a écrit : Ben c'est justement en passant en debug qu'on avait vu qu'il y en avait un dans le registre et l'autre dans le tas, après comme je l'ai déjà dit, p'tet que je me suis trompé dans mon exemple, ca fait un p'tit moment qu'on l'a vu, mais il me semble que c'était ca. |
ca m'etonnerait, en debug VC ne stocke rien dans les registres (enfin, d'une expression a une autre)
quoiqu'il soit le code generé n'a rien a voir la dedans
Marsh Posté le 18-12-2003 à 12:48:00
chrisbk a écrit : |
registre, tas ... tout est dans la pile
Marsh Posté le 18-12-2003 à 12:48:32
Taz a écrit : depuis toujours en C et C++, pourvu qu'elles n'aient pas la même portée |
t'es en train de dire qu'une variable i déclarée pour (pas dans) le for n'est plus accessible après le for?????
On m'aurait menti?
Nan, parce que ca fait 3 ans qu'on me dit l'inverse!
Marsh Posté le 18-12-2003 à 12:49:13
ReplyMarsh Posté le 18-12-2003 à 12:49:26
chrisbk a écrit :
|
je sais bien, merci
sauf que dans l'exemple au dessus mon i n'est pas déclaré DANS le for.......
Marsh Posté le 18-12-2003 à 12:50:14
welcome to the real world.
merci MS ...
Marsh Posté le 18-12-2003 à 12:50:14
harrysauce a écrit : je sais bien, merci |
si, c'est ca la grosse feinte
Marsh Posté le 18-12-2003 à 12:52:13
chrisbk a écrit : |
Bon ben on m'a raconté des cracks pendant 3 ans alors
EDIT : on m'avait toujours dit qu'une variable déclarée pour une boucle (for(int i =0...)) était encore déclarée même après le for....
Marsh Posté le 17-12-2003 à 14:42:36
mettre
char *str = "phrase1";
est-ce corect?
quel sont les defqult de cette initialisation/utilisation?