Bienvenue aux nouveaux arrivants sur FantasPic !

- Pensez à lire les règles durant votre visite, il n'y en a pas beaucoup, mais encore faut-il les respecter .
- N’hésitez pas à faire des remarques et/ou suggestions sur le Forum, dans le but de l'améliorer et de rendre vos prochaines visites plus agréables.
- Vous pouvez regarder votre "panneau de l'utilisateur" afin de configurer vos préférences.
- Un passage par "l'utilisation du forum" est recommandé pour connaître les fonctionnalités du forum.

--- L’équipe FantasPic ---
Forum général sur le langage C !

Modérateur : Jérémy

Petite question
JJE
Passioné
Passioné
Messages : 399
Âge : 83
Enregistré en : novembre 2017
Localisation : Picardie

#1 Message par JJE » mar. 30 juil. 2019 04:28 lien vers la Data-Sheet : Cliquez ici

Bonjour à tous les amateurs de C, quel qu'il soit.
Dans le post donné en lien, je parle d'une routine ASM d'incrémentation d'une variable entière, signée ou non.
Je n'ai pas encore pris le temps de me mettre au C :sifflotte: , quelqu'un aurait-il la gentillesse de me dire comment se comporte le code généré par quelque compilateur C que ce soit, de préférence plusieurs, sur les segments de programme suivants :

1 -

Code : Tout sélectionner

integer i;
= 0x7ffff;
= i+1;// ou i += 1 ou i++ou °°i   


2 -

Code : Tout sélectionner

unsigned integer i;
= 0xfffff;
= i+1;// ou i += 1 ou i++ ou °°i   


Plus précisément, combien vaut i après la dernière instruction, dans chaque cas.
Si 0x8000 dans le premier et/ou 0x0000 dans le deuxième, C donne-t-il un moyen de savoir que c'est fou, en particulier dans le cas de l'usage de la forme i++ ou ++i dans une expression ?
Cordialement

JJE

C'est pas parcequ'on n'a rien à dire qu'il faut fermer sa G....e

Petite question
satinas
Expert
Expert
Messages : 1225
Enregistré en : novembre 2015

#2 Message par satinas » mar. 30 juil. 2019 09:27 lien vers la Data-Sheet : Cliquez ici

Bonjour JJE,

En C chaque variable est typée, sa nature et sa taille sont fixes et ne peuvent changer en cours de route.
Le type int n'a pas une taille déterminée, il dépend de la cpu et du compilateur.
C18, xc8 et MikroC stockent un int sur 16 bits, prenant en charge la partie asm permettant de manipuler une variable 16 bits avec un processeur 8 bits.
A part ça, le C n'en fait guère plus que l'asm. Dans les calculs d'entiers, le signe n'a pas d'importance grâce au complément à 2.
Les 4 syntaxes i = i+1, i += 1, i++, ++i modifient i de la même façon.

int i = 0x7ffff;
unsigned int i = 0x7ffff;
int i = 0xfffff;
unsigned int i = 0xfffff;
Pas d'erreur ni warning C18, il devrait pourtant rouspéter car il tronque à 16 bits -> i = 0xffff dans tous les cas

i = 0x7fff; i++;
Le résultat 0x8000 est le même quel que soit le type de i.
Si i est unsigned, pas de problème, on est passé de +32767 à +32768.
Si i est signed, on est passé de +32767 à -32768.
Le C comme l'asm ne fera rien, c'est au programmeur de faire en sorte qu'il n'y ait pas d'overflow non volontaire.
On peut quand même détecter le changement de signe lors de l'opération en testant le bit haut b15 de i avant et après l'opération.

i = 0xffff; i++;
Le résultat 0x0000 est le même quel que soit le type de i.
Si i est signed, pas de problème, on est passé de -1 à 0.
Si i est unsigned, on a un overflow.

Je ne sais pas si les bits C,Z,N,OV du registre STATUS sont bien à jour après une opération C sur entier car il calcule sur 16 bits.
En C on est éloigné du processeur, alors il ne faut pas trop lui demander si on a bien ou mal fait :)

Si tu installes C18, tu pourras tester tout cela sous simulateur MPLAB, en créant un projet tout simple avec ce source.

Code : Tout sélectionner

#include <p18cxxx.h>
void main(void)
{
  while (1) {
    int i = 0x7fff;
    i += 1;
    i -= 1;
  }
}

Petite question
JJE
Passioné
Passioné
Messages : 399
Âge : 83
Enregistré en : novembre 2017
Localisation : Picardie

#3 Message par JJE » mar. 30 juil. 2019 10:24 lien vers la Data-Sheet : Cliquez ici

Merci Satinas pour cette réponse rapide et détaillée, c'est ce dont je me doutais, ayant pratiqué le MS C/C++ ou C# sur PC, je n'avais aucun souvenir de m'être préoccupé de ce type de problème, c'est pourtant à risque, surtout avec les syntaxes i++ ou ++i. Depuis que j'ai remis la main à l'assembleur pour ces Pics, je suis peut-être devenu trop puriste, je crois qu'il il ne me viendrait pas à l'idée de lancer un calcul sans tester le résultat, du moins je crois.
Encore merci.
Cordialement

JJE

C'est pas parcequ'on n'a rien à dire qu'il faut fermer sa G....e

Petite question
paulfjujo
Avatar de l’utilisateur
Expert
Expert
Messages : 2589
Âge : 73
Enregistré en : juillet 2015
Localisation : 01800
Contact :

#4 Message par paulfjujo » mer. 31 juil. 2019 09:45 lien vers la Data-Sheet : Cliquez ici

bonjour à tous,


la notion signed et unsigned
ou taille Byte 8 bits ou Word 16 bits
est encore plus piegeuse dans le cas de boucle en C

BOUCLE FOR et INDICE
Evolution indice dans Boucle for et test
ATTENTION PIEGE : Avec unsigned int

for(i=0;i<256;i++) // Indice evolue de 000 à 255

for(i=255;i>0;i--) // Indice evolue de 255 à 1 ! mais PAS ZERO

avec unsigned int
for(i=255;i>=0;i--) // Indice evolue de 255 à 0 puis 65535 .....BAD !
....
avec int ou signed int
for(Su=255;Su>=0;Su--) // Indice evolue de 255 à 0 OK
Aide toi, le ciel ou FantasPic t'aidera

Petite question
satinas
Expert
Expert
Messages : 1225
Enregistré en : novembre 2015

#5 Message par satinas » mer. 31 juil. 2019 11:38 lien vers la Data-Sheet : Cliquez ici

Bonjour à tous

avec unsigned int
for(i=255;i>=0;i--) // Indice evolue de 255 à 0 puis 65535 .....BAD !


C'est vrai, Paul, mais le compilateur affiche un warning, la condition i>=0 est toujours vraie
Faut toujours tenir compte des warnings, sinon on risque de passer son temps à chercher les bugs :)

Rectification :
Pour C18, ce n'est pas un warning, c'est un message. Et pour qu'il apparaisse il faut sélectionner "Errors, warnings and messages" dans les paramètres C18 du projet. Par défaut, c'est "Errors, warnings", ce qui cache la peau de banane.

Petite question
JJE
Passioné
Passioné
Messages : 399
Âge : 83
Enregistré en : novembre 2017
Localisation : Picardie

#6 Message par JJE » mer. 31 juil. 2019 20:13 lien vers la Data-Sheet : Cliquez ici

intéressant tout ça, c'est fou les risques pris avec les options par défaut, surtout quand on les modifie et qu'on donne son source à un tier :-D
Cordialement

JJE

C'est pas parcequ'on n'a rien à dire qu'il faut fermer sa G....e

Petite question
paulfjujo
Avatar de l’utilisateur
Expert
Expert
Messages : 2589
Âge : 73
Enregistré en : juillet 2015
Localisation : 01800
Contact :

#7 Message par paulfjujo » jeu. 1 août 2019 11:25 lien vers la Data-Sheet : Cliquez ici

bonjour à tous,

dans la fenetre "Watch values"
on voit bien les valeurs de sortie de boucle
pour is signé on a -1 ( normal)
pour i unsigned on se retrouve avec 65535 .. et c'est donc pas fini ..programme coincé dans la boucle !

Test_boucle_signed_unsigned_MikroC.jpg


Contrairement à C18, malheureusement MikroC est MUET sur cette problematique
toutes les options de "Messages" étant activées
AUCUN messages d'error , ou Warnings

:!!: donc , double ACHTUNG, PASST AUF !

0 1 mikroCPIC1618.exe -MSF -DBG -pP18F47J53 -RA -C -DL -O11111114 -fo48 -N"^C
C:\_MikroC\_MesProjets_MikroC\_18F47J53_Click\Test_signed_unsigned_Boucle.mcppi" -SP"^C
C:\_MikroC\mikroC PRO for PIC\Defs\" -SP"^C
C:\_MikroC\mikroC PRO for PIC\uses\P18\" -SP"^C
C:\_MikroC\_M
0 1139 Available RAM: 3739 [bytes], Available ROM: 131064 [bytes]
0 122 Compilation Started P18F47J53.c
3882 123 Compiled Successfully P18F47J53.c
0 122 Compilation Started
_Lib_Delays.c
172 123 Compiled Successfully
_Lib_Delays.c
0 122 Compilation Started Test_signed_unsigned_Boucle.c
74 123 Compiled Successfully Test_signed_unsigned_Boucle.c
0 127 All files Compiled in 125 ms
0 1144 Used RAM (bytes): 4 (1%) Free RAM (bytes): 3735 (99%) Used RAM (bytes): 4 (1%) Free RAM (bytes): 3735 (99%)
0 1144 Used ROM (bytes): 146 (1%) Free ROM (bytes): 130918 (99%) Used ROM (bytes): 146 (1%) Free ROM (bytes): 130918 (99%)
0 125 Project Linked Successfully Test_signed_unsigned_Boucle.mcppi
0 128 Linked in 47 ms
0 129 Project 'Test_signed_unsigned_Boucle.mcppi' completed: 687 ms
0 103 Finished successfully: 01 août 2019, 11:10:19 Test_signed_unsigned_Boucle.mcppi
Vous n’avez pas les permissions nécessaires pour voir les fichiers joints à ce message.
Aide toi, le ciel ou FantasPic t'aidera

Petite question
JJE
Passioné
Passioné
Messages : 399
Âge : 83
Enregistré en : novembre 2017
Localisation : Picardie

#8 Message par JJE » jeu. 1 août 2019 14:55 lien vers la Data-Sheet : Cliquez ici

bonjour à tous, si je résume, charge est au programmeur de choisir convenablement le type (signed ou unsigned) et l'étendue (byte, int ou long d'une variable avec laquelle il doit manipuler un concept numérique, et, après il ne prend plus aucune précaution, en espérant ne pas s'être trompé car ce doit être parfois dificile à trouver.
Je ne pensais pas déclencher une telle discussion :sifflotte:
Cordialement

JJE

C'est pas parcequ'on n'a rien à dire qu'il faut fermer sa G....e


Retourner vers « Langage C »

Qui est en ligne

Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 36 invités