Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1101 connectés 

 

 

 Mot :   Pseudo :  
 
 Page :   1  2  3  4  5  6
Auteur Sujet :

[C/C++] Défi: Trouvez les bogues ! (n°42)

n°181406
Ace17
Posté le 24-07-2002 à 11:05:13  profilanswer
 

Reprise du message précédent :

musaran a écrit a écrit :

 
[B]Trouvez le bogue !(9)[/B]

Code :
  1. #include <stdio.h>
  2. int main()
  3. {
  4. char * chaineC = "Hello world";
  5. printf("%s\n" , chaineC) ;
  6. return 0;
  7. }


Ce code contient un bogue en puissance.
Un débutant faisant des essais pourrait tomber dessus... ou pas.




 
J'ai toujours pas compris ou était l'erreur


Message édité par Ace17 le 24-07-2002 à 11:05:54
mood
Publicité
Posté le 24-07-2002 à 11:05:13  profilanswer
 

n°182296
Musaran
Cerveaulté
Posté le 25-07-2002 à 02:46:12  profilanswer
 

"Hello world" est une chaîne littérale, en conséquence constante, faite de "const char".
 
"char * chaineC =" est un pointeur de caractères sans plus.
donc, il permet de faire "chaineC[6]='W'" par exemple, et de modifier une constante.
 
C'est pas une erreur ça ?


---------------
Bricocheap: Montage de ventilo sur paté de mastic silicone
n°182298
chrisbk
-
Posté le 25-07-2002 à 02:59:49  profilanswer
 

boaf, non, j'en fais plein des char *roger = "toto"
 
d'ailleurs tu dois meme pouvoir le modifier
 
 
 
edit : nan ca plante lamentablement :D (la modif)


Message édité par chrisbk le 25-07-2002 à 03:01:27
n°182337
Ace17
Posté le 25-07-2002 à 09:26:25  profilanswer
 

Normal, il ne mets pas les chaines statiques au meme endroit que les variables dans la mémoire

n°182339
Ace17
Posté le 25-07-2002 à 09:27:56  profilanswer
 

musaran a écrit a écrit :

"Hello world" est une chaîne littérale, en conséquence constante, faite de "const char".
 
"char * chaineC =" est un pointeur de caractères sans plus.
donc, il permet de faire "chaineC[6]='W'" par exemple, et de modifier une constante.
 
C'est pas une erreur ça ?
 




 
Je trouve pas... Apres tout le code que tu as donné marche tres bien. De plus qui irait s'amuser a modifier cette chaine? D'apres toi, alors, il ne faudrait jamais utiliser de chaines statiques?

n°182345
LetoII
Le dormeur doit se réveiller
Posté le 25-07-2002 à 09:30:46  profilanswer
 

Ace17 a écrit a écrit :

 
 
Je trouve pas... Apres tout le code que tu as donné marche tres bien. De plus qui irait s'amuser a modifier cette chaine? D'apres toi, alors, il ne faudrait jamais utiliser de chaines statiques?




 
C'est tout con, au bout de 500 lignes de code tu sais plus forcément sur quoi pointe ta variable et tu tante une modification d'une chaîne qui aurait du rester constante.


---------------
Le Tyran
n°182357
Ace17
Posté le 25-07-2002 à 09:42:15  profilanswer
 

Je vois :)
Ce qu'il manque alors c'est tout simplement le "const"

n°182361
LetoII
Le dormeur doit se réveiller
Posté le 25-07-2002 à 09:42:53  profilanswer
 

Ace17 a écrit a écrit :

Je vois :)
Ce qu'il manque alors c'est tout simplement le "const"




 
Ouai :D


---------------
Le Tyran
n°183100
tanguy
Posté le 25-07-2002 à 22:14:52  profilanswer
 

letoII a écrit a écrit :

 
C'est tout con, au bout de 500 lignes de code tu sais plus forcément sur quoi pointe ta variable et tu tante une modification d'une chaîne qui aurait du rester constante.




 
exact
en C++ des const il faut en mettre partout et c'est bien sympa : on obtient un code plus robuste pour pas cher.
 
d'ailleurs const a été étendu pour le C99 il me semble. la preuve que c'est bien :)
 

Ace17 a écrit a écrit :

 
Je trouve pas... Apres tout le code que tu as donné marche tres bien. De plus qui irait s'amuser a modifier cette chaine? D'apres toi, alors, il ne faudrait jamais utiliser de chaines statiques?




non static à plusieurs significations mais aucune ne correspond à const. se sont 2 choses différentes et complémentaires
 
d'ailleurs en C++ les #define du préprocesseur on essaye au maximum de les remplacer par des static const, ca pose moins de problèmes.

n°183293
Musaran
Cerveaulté
Posté le 26-07-2002 à 01:13:35  profilanswer
 

Ace17 a écrit a écrit :

De plus qui irait s'amuser a modifier cette chaine?


Forme générale de la loi de Murphy: Si quelque chose peut foirer, alors ça va foirer.
 
Si tu laisses un truc pas protégé dans ton programme, alors c'est celui-là que quelqu'un va modifier.
 
 
Pour les const, oui, il faudrait les mettre systématiquement et les enlever seulement quand on sait pourquoi.


Message édité par Musaran le 26-07-2002 à 01:15:16

---------------
Bricocheap: Montage de ventilo sur paté de mastic silicone
mood
Publicité
Posté le 26-07-2002 à 01:13:35  profilanswer
 

n°183308
bjone
Insert booze to continue
Posté le 26-07-2002 à 04:07:07  profilanswer
 

hem...
 
fodrait éviter de penser que le const protège quoi que ce soit...
 
le const vous protège contre vous-même....
 
pas contre les autres....

n°183318
LetoII
Le dormeur doit se réveiller
Posté le 26-07-2002 à 07:31:04  profilanswer
 

bjone a écrit a écrit :

hem...
 
fodrait éviter de penser que le const protège quoi que ce soit...
 
le const vous protège contre vous-même....
 
pas contre les autres....




 
effectivement sufit de faire un cast (je crois que c le static_cast mais je suis plus sûr) pour virer un const, mais bon quand on cherche la merde faut pas s'étonner après de se prendre un truc dans la gueule :D


Message édité par LetoII le 26-07-2002 à 07:31:29

---------------
Le Tyran
n°183321
toum toum
Posté le 26-07-2002 à 08:17:41  profilanswer
 

pour le détail, c'et un const_cast

n°183326
LetoII
Le dormeur doit se réveiller
Posté le 26-07-2002 à 08:33:42  profilanswer
 

toum toum a écrit a écrit :

pour le détail, c'et un const_cast




 
suis-je bête  :sarcastic:


---------------
Le Tyran
n°184129
Musaran
Cerveaulté
Posté le 27-07-2002 à 00:58:14  profilanswer
 

Ce sont des guides pour savoir quand on fait une bêtise.
Ça n'a pas vocation à empêcher le viol, juste le signaler...


---------------
Bricocheap: Montage de ventilo sur paté de mastic silicone
n°184131
bjone
Insert booze to continue
Posté le 27-07-2002 à 01:01:13  profilanswer
 

musaran a écrit a écrit :

Ce sont des guides pour savoir quand on fait une bêtise.
Ça n'a pas vocation à empêcher le viol, juste le signaler...




 
restez poli :D

n°189460
gilou
Modérateur
Modzilla
Posté le 04-08-2002 à 02:53:31  profilanswer
 

Au fait, en lisant les commentaires, il m'a semblé que la durée de vie de la chaine allouée n'etait pas claire pour certains.
Je met ici ce qu'il me semble etre juste (sans rentrer dans le detail de ou les structures de données correspondant aux variables vont etre allouées). S'il y a des erreurs, n'hesitez pas a les corriger.
 
char chaineC[] = "Hello World";
Le compilo va creer un tableau de 12 caracteres, le remplir avec les 11 caracteres puis un 0 final et stocker celà dans un segment de données specifique (a priori, .rodata [pour read-only data]).
A l'appel du bloc de programme declarant chaineC, variable "auto", il y a allocation sur la stack et copie du tableau stocké a la compil, et association du tableau copié avec la variable chaineC.
 
char *chaineC = "Hello World";
Le compilo va creer un tableau de 12 caracteres, le remplir avec les 11 caracteres puis un 0 final et stocker celà dans un segment de données specifique (a priori, .rodata [pour read-only data]).
A l'appel du bloc de programme declarant chaineC, variable "auto", il y a allocation d'un pointeur sur la stack, rangement de l'adresse du tableau dans le pointeur, et association du pointeur avec la variable chaineC.  
 
La durée de vie de la chaine et sa visibilité est celle de la variable, donc limitée au bloc ou la variable est declarée.
 
Une des erreurs possibles avec l'ecriture  
char *chaineC = "Hello World";
c'est de vouloir reutiliser chaineC plus tard, dans le bloc, sans se souvenir comment il a ete initialisé, et de faire un free(chaineC) avant de lui allouer une nouvelle zone memoire pour une autre chaine.
 
Note: (pour faire simple, je me limite au cas du tableau).
 
Si on avait declaré:
static char chaineC[] = "Hello World";
Le compilo va creer un tableau de 12 caracteres, le remplir avec les 11 caracteres puis un 0 final et stocker celà dans un segment de données specifique (a priori, .data [pour les variables static initialisées]).  
A l'appel du bloc de programme declarant chaineC, variable "static", il y a association du tableau avec la variable chaineC.
La durée de vie du tableau est le programme, mais son accessibilité est celui de la variable, donc le bloc ou la variable est declarée.
 
Si on avait declaré:  
const char chaineC[] = "Hello World";
il se produirait la meme chose que sans le qualificateur const, mais de plus le compilateur verifiera a la compilation que l'on essaye pas de modifier chaineC, et a l'execution, la zone memoire allouée pour le tableau aura un flag indiquant qu'elle est read-only.
 
A+,


Message édité par gilou le 05-08-2002 à 05:56:56

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°189714
Musaran
Cerveaulté
Posté le 05-08-2002 à 03:33:30  profilanswer
 

  • Tu vas chercher bien compliqué...

    Code :
    1. char  tabChar1[] = {'H','e','l','l','o',' ','W','o','r','l','d','\0'};
    2. char  tabChar2[] = "Hello World";
    3. char *ptrChar    = "Hello World";

    tabChar1 est un tableau de taille appropriée (12).

Si c'est dans une fonction, le tableau est alloué localement, donc sur la pile. Et désalloué à la "}" fermant le bloc de code.
Qu'il soit copié depuis un original global ou généré par le code exécutable, on n'en sait rien, et on n'a pas besoin de le savoir...
 
tabChar2 est exactement pareil à tabChar1.
C'est juste une forme d'écriture simplifiée...
 
ptrChar est uniquement un pointeur. Il est initialisé pour désigner...
..."Hello World", qui est ici un tableau global(i.e. statique) [B]constant[/B]. J'insiste là-dessus.
Il n'y a aucune allocation/désallocation de chaîne.
 
 

  • free ne doit être fait que sur des adresses obtenues avec malloc/realloc, on est bien d'accord !


 

  • Ta remarque sur le tableau statique local est pertinente, mais incomplète...

Une variable statique locale est initialisée à la première éxécution de sa déclaration/définition.
Cela implique qu'elle est accompagnée par un booléen caché.
Ce comportement étrange est destiné aux types C++ avec constructeurs: S'ils étaient éxécutés au niveau global, ils pourraient dépendre de valeurs pas encore prêtes.
Dans ce code, o n'est jamais construit:

Code :
  1. struct O{
  2. O(){cout << "Init\n";}
  3. };
  4. void f(){
  5. if(false)
  6.  static O o;
  7. }


 

  • Ne sont allouées dans une zone mémoire read-only que les constantes connues dès la compilation.

Exit donc les types avec constructeurs, les variables statiques locales, les pointeurs/références. Mêmes constants, il sont construits à l'exécution !
 
 

  • Là, on cherche vraiment la petite bête dans les recoins sombres du langage...


Bon, personne ne trouves les deux derniers bogues ?


Message édité par Musaran le 05-08-2002 à 03:35:37

---------------
Bricocheap: Montage de ventilo sur paté de mastic silicone
n°189715
deathsharp
Posté le 05-08-2002 à 03:40:16  profilanswer
 

depuis quand on fou un constructeur dans une struct


---------------
What butter and whiskey won't cure, there is no cure for.
n°189716
Musaran
Cerveaulté
Posté le 05-08-2002 à 03:43:41  profilanswer
 

Depuis que je suis en C++ :D.
 
Si ça dérange, il suffit de faire

Code :
  1. class O{
  2. public:


---------------
Bricocheap: Montage de ventilo sur paté de mastic silicone
n°189717
deathsharp
Posté le 05-08-2002 à 03:44:57  profilanswer
 

on met pas trop de constructeur dans les structs en general :/
sinon a part ke ca ma frapper v quand meme essayer de lire le reste :D
mais bon, j'aurais peut etre du suivre du debut


---------------
What butter and whiskey won't cure, there is no cure for.
n°189721
gilou
Modérateur
Modzilla
Posté le 05-08-2002 à 05:54:10  profilanswer
 

Citation :

Qu'il soit copié depuis un original global ou généré par le code exécutable, on n'en sait rien, et on n'a pas besoin de le savoir...


Ca, ca depends de ce que tu fais. Si tu ecris un compilo ou un un debugger...
 

Citation :

Ta remarque sur le tableau statique local est pertinente, mais incomplète...


Elle se limitait au cas du C.
 
A+,


Message édité par gilou le 05-08-2002 à 05:59:24

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°190459
Musaran
Cerveaulté
Posté le 06-08-2002 à 02:59:23  profilanswer
 

gilou a écrit a écrit :

Ca, ca depends de ce que tu fais. Si tu ecris un compilo ou un un debugger...


Je me plaçais dans le cas d'un utilisateur du langage, sans plus.


Message édité par Musaran le 06-08-2002 à 02:59:57

---------------
Bricocheap: Montage de ventilo sur paté de mastic silicone
n°191189
Musaran
Cerveaulté
Posté le 07-08-2002 à 00:44:27  profilanswer
 

C'est vrai qu'il vaut mieux réserver les "struct" aux types simples... pas de ctor/dtor, pas de méthode virtuelle, voire pas de méthodes du tout.
 
Bon, allez...
[B]Solution (14):[/B]

Code :
  1. printf("Entrez un caractère :\m" ) ;


La séquence d'échappement '\m' n'existe pas et le comportement est indéfini.
Vous l'avez vraiment pas vu, ou c'est la flemme de le signaler ?
 
[B]Solution (15):[/B]

Code :
  1. printf("Le caractère de valeur 128 est: %c\n",128) ;
  2. printf("Vous avez entré la lettre ""'%s'"" qui a pour valeur: %u.\n",in,in) ;
  3. unsigned char ; //de    0 à 255.
  4.   signed char ; //de -128 à 127.
  5.          char ; //type distinct, signé ou pas selon l'implémentation.

Donc, utiliser 128 comme valeur de char est incorrect.
Et afficher un char par "%u" (unsigned int) est incorrect, il faut utliser %i ou %d (signed int) qui peut recevoir de -127 à 255.
Dans les deux cas: comportement indéfini.


Message édité par Musaran le 07-08-2002 à 00:45:21

---------------
Bricocheap: Montage de ventilo sur paté de mastic silicone
n°191191
Musaran
Cerveaulté
Posté le 07-08-2002 à 00:45:58  profilanswer
 

Bon, je vous sent pas trop en forme alors j'en mets un petit...
 
[B]Trouvez le bogue !(16)[/B]

Code :
  1. int DiffAdresse(void* ad1, void* ad2){
  2. return (char*)ad1-(char*)ad2;
  3. }

Un bon compilateur peut émettre un warning.


---------------
Bricocheap: Montage de ventilo sur paté de mastic silicone
n°191252
LetoII
Le dormeur doit se réveiller
Posté le 07-08-2002 à 08:15:18  profilanswer
 

musaran a écrit a écrit :

Bon, je vous sent pas trop en forme alors j'en mets un petit...
 
[B]Trouvez le bogue !(16)[/B]

Code :
  1. int DiffAdresse(void* ad1, void* ad2){
  2. return (char*)ad1-(char*)ad2;
  3. }

Un bon compilateur peut émettre un warning.




 
Effectivement, normalement il signal une oppération non valide sur des pointeurs. En effet la soustraction de deux pointeurs n'as pas vraiment de sens dans l'absolue.


---------------
Le Tyran
n°191870
Musaran
Cerveaulté
Posté le 08-08-2002 à 04:15:30  profilanswer
 

Mais qu'est-ce que tu racontes ?

Code :
  1. int array[10] ;
  2. int* ptr1 = &array[1] ;
  3. int* ptr3 = &array[3] ;
  4. ptr3-ptr1 ;//nombre d'int (pas d'octets) les séparant: 2
  5. ptr1-ptr3 ;//-2
  6. ptr1+5    ;//adresse du 6 ème int du tableau
  7. 5+ptr1    ;//idem
  8. ptr1+ptr3 ;//non-sens
  9. ptr1*ptr3 ;//non-sens
  10. ptr1/ptr3 ;//non-sens

C'est parfaitement défini et standard.


---------------
Bricocheap: Montage de ventilo sur paté de mastic silicone
n°191873
LetoII
Le dormeur doit se réveiller
Posté le 08-08-2002 à 08:19:40  profilanswer
 

musaran a écrit a écrit :

Mais qu'est-ce que tu racontes ?

Code :
  1. int array[10] ;
  2. int* ptr1 = &array[1] ;
  3. int* ptr3 = &array[3] ;
  4. ptr3-ptr1 ;//nombre d'int (pas d'octets) les séparant: 2
  5. ptr1-ptr3 ;//-2
  6. ptr1+5    ;//adresse du 6 ème int du tableau
  7. 5+ptr1    ;//idem
  8. ptr1+ptr3 ;//non-sens
  9. ptr1*ptr3 ;//non-sens
  10. ptr1/ptr3 ;//non-sens

C'est parfaitement défini et standard.




 
T deux pointeurs sont sur le même tableau, bien sûr que ça a un sens, mais si tu prend deux pointeurs quelconques je suis désolé mais ça n'a pas vraiment de sens en sois.
 
Maintenent je me suis peut être emballé et le compilo va peut être pas mettre de warning (encoreque je suis sûr de l'avoir vu qq part)


Message édité par LetoII le 08-08-2002 à 08:31:46

---------------
Le Tyran
n°191876
LetoII
Le dormeur doit se réveiller
Posté le 08-08-2002 à 08:28:29  profilanswer
 

D'autre part à par le warning sur lea différence de pointeur il peut aussi gueuler à cause du cast implicite.
 

Code :
  1. return (int)((char *)adr1 - (char*)adr2);


 
comme ça, ça passe mieu


---------------
Le Tyran
n°192636
Musaran
Cerveaulté
Posté le 09-08-2002 à 03:34:18  profilanswer
 

letoII a écrit a écrit :

T deux pointeurs sont sur le même tableau, bien sûr que ça a un sens, mais si tu prend deux pointeurs quelconques je suis désolé mais ça n'a pas vraiment de sens en sois.
 
Maintenent je me suis peut être emballé et le compilo va peut être pas mettre de warning (encoreque je suis sûr de l'avoir vu qq part)



Le compilateur ne vérifies pas que les pointeurs sont sur le même tableau, et de toutes façon cette fonction n'a aucun moyen de le savoir.
Son rôle est de donner le nombre d'octets séparant deux adresses, je ne me soucies pas du sens que ça a pour l'utilisateur !
 
char signifiant octet, ses pointeurs n'ont aucun problème d'alignement, on peut toujours en faire une différence...
 

letoII a écrit a écrit :

D'autre part à par le warning sur lea différence de pointeur il peut aussi gueuler à cause du cast implicite.


Tu me scies !
Tu brûles, mais ta réponse est à coté de la plaque !


Message édité par Musaran le 09-08-2002 à 03:35:54

---------------
Bricocheap: Montage de ventilo sur paté de mastic silicone
n°192662
LetoII
Le dormeur doit se réveiller
Posté le 09-08-2002 à 07:33:12  profilanswer
 

musaran a écrit a écrit :

Le compilateur ne vérifies pas que les pointeurs sont sur le même tableau, et de toutes façon cette fonction n'a aucun moyen de le savoir.
Son rôle est de donner le nombre d'octets séparant deux adresses, je ne me soucies pas du sens que ça a pour l'utilisateur !
 
char signifiant octet, ses pointeurs n'ont aucun problème d'alignement, on peut toujours en faire une différence...
 
Tu me scies !
Tu brûles, mais ta réponse est à coté de la plaque !




 
Heu le warning sur le cast implicite je l'ai déjà vu.


---------------
Le Tyran
n°192663
LetoII
Le dormeur doit se réveiller
Posté le 09-08-2002 à 07:39:55  profilanswer
 

Et puis les adresses étant toutes positives tu va avoir des pb en renvoyant ton résultat sur un int, typiquement en 32 bit il faudrait que tu renvoie ton résultat sur 33bits: si tu fais 0 - l'adresse la plus grande tu va avoir un problème.


---------------
Le Tyran
n°192664
LetoII
Le dormeur doit se réveiller
Posté le 09-08-2002 à 08:15:07  profilanswer
 

LetoII a écrit a écrit :

Et puis les adresses étant toutes positives tu va avoir des pb en renvoyant ton résultat sur un int, typiquement en 32 bit il faudrait que tu renvoie ton résultat sur 33bits: si tu fais 0 - l'adresse la plus grande tu va avoir un problème.




 
Heu je sais pas si j'ai été bien clair là  :heink:


---------------
Le Tyran
n°193312
Musaran
Cerveaulté
Posté le 10-08-2002 à 02:18:41  profilanswer
 

Tu as juste oublié de préciser signed int.
 
[B]Solution (16):[/B]
On suppose ici qu'un entier peut recevoir la différence de deux pointeurs, donc que les pointeurs et les entiers sont de même taille.
 
Ce n'est pas garanti !
Par exemple, une machine peut avoir des registres 16 bits mais adresser 4Go de RAM, ce qui requiert des pointeurs 32 bits.
 
Bonne version:

Code :
  1. #include <stddef.h>
  2. ptrdiff_t DiffAdresse(void* ad1, void* ad2){
  3. return (char*)ad1-(char*)ad2;
  4. }


 
Sur ma machine, ptrdiff_t est synonyme de int.
Donc effectivement, faire la différence d'adresses trop distantes risque de dépasser.
 
A mon avis:
-On ne doit effectivement faire de différence de pointeur que s'ils pointe le même tableau.
-Un tableau ne peut pas être plus grand que la moitié de l'espace adressable.
 
Bogue bonus:
Cette fonction ne déclare pas ses arguments const, elle ne peut être appelée avec valeurs const.
Alors qu'elle le pourrait très bien !


Message édité par Musaran le 10-08-2002 à 02:20:46

---------------
Bricocheap: Montage de ventilo sur paté de mastic silicone
n°193317
Musaran
Cerveaulté
Posté le 10-08-2002 à 02:22:43  profilanswer
 

[B]Trouvez le bogue n° 17![/B]

Code :
  1. float a= 0.5 ;//OK
  2. float b= 0.6 ;//warning: perte de précision



---------------
Bricocheap: Montage de ventilo sur paté de mastic silicone
n°194430
LetoII
Le dormeur doit se réveiller
Posté le 13-08-2002 à 08:49:57  profilanswer
 

musaran a écrit a écrit :

[B]Trouvez le bogue n° 17![/B]

Code :
  1. float a= 0.5 ;//OK
  2. float b= 0.6 ;//warning: perte de précision


 




 
Et t'as ça avec quoi comme compilo, par ce que moi j'ai essayé ça passe (ts warning activés)


---------------
Le Tyran
n°194439
El_gringo
Posté le 13-08-2002 à 09:08:39  profilanswer
 

musaran a écrit a écrit :

[B]Trouvez le bogue n° 17![/B]

Code :
  1. float a= 0.5 ;//OK
  2. float b= 0.6 ;//warning: perte de précision


 




 
Moi j'aurai imaginé qu'il mettrait des warnings ds les 2 cas, et que pour éviter ça, il faut :

Code :
  1. float a= 0.5f ;
  2. float b= 0.6f ;


 
parce que quand on écrit un chiffre avec virgule en dur comme ça, si on précise pas que c un float (avec le "f" ), il considère que c un double, non !?


Message édité par El_gringo le 13-08-2002 à 09:09:21
n°194440
LetoII
Le dormeur doit se réveiller
Posté le 13-08-2002 à 09:10:16  profilanswer
 

El_Gringo a écrit a écrit :

 
 
Moi j'aurai imaginé qu'il mettrait des warnings ds les 2 cas, et que pour éviter ça, il faut :

Code :
  1. float a= 0.5f ;
  2. float b= 0.6f ;


 
parce que quand on écrit un chiffre avec virgule en dur comme ça, si on précise pas que c un float (avec le "f" ), il considère que c un double, non !?




 
ha mon avis ça doit dépendre des compilo.


---------------
Le Tyran
n°194989
Musaran
Cerveaulté
Posté le 14-08-2002 à 03:17:36  profilanswer
 

El_gringo a partiellement répondu.
 
[B]Solution n°17:[/B]
Les constantes de la forme n.n ou nEn sont des doubles, c'est officiel.
 
0.5 = 5/10 = 1/2 qui est une division   exacte (en binaire), donc décimales binaires finissant par des 0.
0.6 = 6/10 = 3/5 qui est une division inexacte (en binaire), donc décimales binaires répétées sans fin.
Quand on tronque un double en flottant, perdre des 0 ne change pas la valeur. Perdre des 1 si.
 
Donc float b= 0.5 ne génère pas d'alerte, et c'est normal.
Pareil avec n.25, n.125 ect...
Cela dit, on pourrait en souhaiter une quand même.
 
Pour éviter tout problème, penser à typer correctement dès le départ:

Code :
  1. float c= 0.6f ;
  2. float d= (float)6/(float)10 ;
  3. float e= float(6)/float(10) ; //C++


Mon compilateur est Visual C++ 6, et pour une fois il agit correctement.
 
Bon, je fais une pause.
Mais c'est pas interdit de prendre le relais :D.


Message édité par Musaran le 14-08-2002 à 03:19:04

---------------
Bricocheap: Montage de ventilo sur paté de mastic silicone
n°195018
LetoII
Le dormeur doit se réveiller
Posté le 14-08-2002 à 08:18:27  profilanswer
 

musaran a écrit a écrit :

Mon compilateur est Visual C++ 6, et pour une fois il agit correctement.
 




 
C effectivement suffisament rare pour être signalé :D


Message édité par LetoII le 14-08-2002 à 08:18:45

---------------
Le Tyran
n°222621
Musaran
Cerveaulté
Posté le 02-10-2002 à 02:52:06  profilanswer
 

Juste une précision sur les "chaînes littérales" utilisées dans une expression:
(je viens de l'apprendre ici: http://david.tribble.com/text/cdiffs.htm)
 
En C(99), elles sont converties en char*.
En C++98, elles sont converties en const char*, puis en char*. Mais cette dernière conversion est dépréciée.
Dans les deux cas, elles ne sont pas modifiables.
 
Soignons bien notre code, si nous ne voulons pas faire partie des "break millions lines of code".
 
Je me demande comment une telle bévue a été possible, alors que le typage C++ est censé être très sur ?


---------------
Bricocheap: Montage de ventilo sur paté de mastic silicone
mood
Publicité
Posté le   profilanswer
 

 Page :   1  2  3  4  5  6

Aller à :
Ajouter une réponse
 

Sujets relatifs
comment trouvez mon site???[JS] JEU: Trouvez l'erreur :o)
Un petit défi : echecs et IA[DEFI DELPHI] - Delayer un buffer pour les Visualization Winamp
Defi programmation JAVA ou autreDefi PHP n°3 !!!
Plus de sujets relatifs à : [C/C++] Défi: Trouvez les bogues ! (n°42)


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR