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

un piege que si l'on s'en sert
paulfjujo
Avatar de l’utilisateur
Expert
Expert
Messages : 2589
Âge : 73
Enregistré en : juillet 2015
Localisation : 01800
Contact :

#1 Message par paulfjujo » ven. 29 sept. 2017 17:24

bonjour à tous,

Dans la série LES PIEGES à IONS ... humour!!

Une fois n'est pas coutume, j'ai voulu utiliser une variable unsigned char , un byte quoi .
dans une boucle for

Code : Tout sélectionner


char CRam1
[20];
void CRLF(void); //just a CR LF printout
unsigned char Ratio;
....
for (
Ratio=0;Ratio<255;Ratio++)
 {
 
ByteToStr(Ratio,CRam1);
 
UART1_Write_Text(CRam1);          
 
CRLF1();
 }
 
CRLF1();
 while(
1);
  


imprime les valeurs de 0 à 254 .. NORMAL

et avec cec i

Code : Tout sélectionner


  
for (Ratio=0;Ratio<256;Ratio++)
 {
 
ByteToStr(Ratio,CRam1);          
 
UART1_Write_Text(CRam1);    
 
CRLF1();                           
 }
 
CRLF1();
 while(
1);
 



Ratio pouvant prendre les valeurs de 0 à 255 .. reste donc inferieur à 256
on pourrait s'attendre à imprimer les valeurs de 0 à 255 !
Mais Non, c'est pas fini !

Tester le .. :!!:
part en boucle sans fin et donc plante le programme !

j'ai posé la question sur MikroC Forum
ils proposent cette solution compréhensive (avec le turn over 8 bits 255+1 =0) MAIS assez dérangeante
la notion du passage au maximum 255 étant abstraite.

Code : Tout sélectionner


Ratio 
0;
do {
  ...
  
Ratio++;
} while (
Ratio>0);
 



Habituellement je travaille toujours avec unsigned int dans les boucles for ou while ..
donc I faudra s'attendre à ce qu'un jour ,une boucle comme celle ci

Code : Tout sélectionner


unsigned int IRatio
;
for (
IRatio=0;Iratio<65536;IRatio++)
{
.. 
blablabla


parte en sucette aussi !

on en conclura qu'il ne faut pas s'approcher trop près des frontières ,
même si on est dans la Convention de Schengen !
Aide toi, le ciel ou FantasPic t'aidera

un piege que si l'on s'en sert
satinas
Expert
Expert
Messages : 1225
Enregistré en : novembre 2015

#2 Message par satinas » ven. 29 sept. 2017 19:08

Salut Paul,

gcc détecte l'anomalie et envoie un warning de compilation sur la ligne for
warning: comparison is always true due to limited range of data type [-Wtype-limits]

Code : Tout sélectionner

for (unsigned char i=0; ; i++) {
  blabla;
  if (i == 255) break;
}

un piege que si l'on s'en sert
Jérémy
Administrateur du site
Administrateur du site
Messages : 2722
Âge : 44
Enregistré en : juillet 2015
Localisation : Dans le sud
Contact :

#3 Message par Jérémy » ven. 29 sept. 2017 19:56

Bonsoir à tous,

Effectivement ce n'est pas très sérieux ça ; Je n'ai jamais rencontré ce problème, mais je me serais fait avoir et un bon moment avant de trouver .
Car pour moi, ca fait partis des acquis !

Une valeur arrive à 255 et repasse à zéro si on l'incrémente.
Merci Paul pour cette information qu'il va falloir que je retienne
C'est en faisant des erreurs, que l'on apprend le mieux !!!

un piege que si l'on s'en sert
venom
Avatar de l’utilisateur
Confirmé
Confirmé
Messages : 953
Âge : 38
Enregistré en : avril 2016
Localisation : Klyntar
Contact :

#4 Message par venom » ven. 29 sept. 2017 20:24

Bonjour,

En effet merci pour l'info. :wink:






@++
Mon site web
Mon discord : venom#4888

un piege que si l'on s'en sert
paulfjujo
Avatar de l’utilisateur
Expert
Expert
Messages : 2589
Âge : 73
Enregistré en : juillet 2015
Localisation : 01800
Contact :

#5 Message par paulfjujo » ven. 29 sept. 2017 20:54

bonsoir Satinas,

satinas a écrit :gcc détecte l'anomalie et envoie un warning de compilation sur la ligne for
warning: comparison is always true due to limited range of data type [-Wtype-limits]

Code : Tout sélectionner

for (unsigned char i=0; ; i++) {
  blabla;
  if (i == 255) break;
}


A part que MikroC NE VOIT RIEN D'ANORMAL ... pas de warning


0 1 mikroCPIC1618.exe -MSF -DBG -pP18F26K22 -RA -C -O00000114 -fo16 -N"C:\_MikroC\_MesProjets_MikroC\18F26K22_test_for_with_byte.mcppi" -SP"C:\_MikroC\mikroC PRO for PIC\Defs\" -SP"C:\_MikroC\mikroC PRO for PIC\uses\P18\" -SP"C:\_MikroC\_MesProjets_MikroC\" -SP"C:\_MikroC\_MesProjets_MikroC\common\" -SP"C:\_MikroC\_PICKIT2\" -SP"D:\_Editeur\" "_18F26K22_test_for_byte.c" "__Lib_Math.mcl" "__Lib_MathDouble.mcl" "__Lib_System.mcl" "__Lib_Delays.mcl" "__Lib_CType.mcl" "__Lib_CString.mcl" "__Lib_CStdlib.mcl" "__Lib_CMath.mcl" "__Lib_Conversions.mcl" "__Lib_OneWire.mcl" "__Lib_ADC_K22_B.mcl" "__Lib_EEPROM_1024.mcl" "__Lib_I2C_c34b12.mcl" "__Lib_PWM_c21.mcl" "__Lib_UART_c67b67.mcl"
0 1139 Available RAM: 3875 [bytes], Available ROM: 65536 [bytes]
0 122 Compilation Started P18F26K22.c
2621 123 Compiled Successfully P18F26K22.c
0 122 Compilation Started __Lib_Delays.c
172 123 Compiled Successfully __Lib_Delays.c
0 122 Compilation Started _18F26K22_test_for_byte.c
141 1509 Generated baud rate is 19231 bps (error = 0.16 percent) _18F26K22_test_for_byte.c
171 123 Compiled Successfully _18F26K22_test_for_byte.c
0 127 All files Compiled in 62 ms
0 1144 Used RAM (bytes): 99 (3%) Free RAM (bytes): 3776 (97%) Used RAM (bytes): 99 (3%) Free RAM (bytes): 3776 (97%)
0 1144 Used ROM (bytes): 948 (1%) Free ROM (bytes): 64588 (99%) Used ROM (bytes): 948 (1%) Free ROM (bytes): 64588 (99%)
0 125 Project Linked Successfully 18F26K22_test_for_with_byte.mcppi
0 128 Linked in 47 ms
0 129 Project '18F26K22_test_for_with_byte.mcppi' completed: 297 ms
0 103 Finished successfully: 29 sept. 2017, 20:34:43 18F26K22_test_for_with_byte.mcppi


voici le code complet de test , ci dessous

Code : Tout sélectionner

#define Config "18F26K22_Fosc_interne_16MHz.cfgsch"

#define PROCESSOR "18F26K22"
#define OSCILLATEUR_INTERNE
#define POWER_SUPPLY  " 5V"
#define FOSC "16.0"  // MHz
#define BAUD 19200  // UART1  COM3 prolific ou COM13 Prolific
#define CLS 12
#define CR 0x0D
#define LF 10
#define TAB 9
#define BACK 8
#define Beep 7
#define Separator 0x20   // space


#ifndef Byte
#define Byte unsigned char
#endif

#ifndef Word
#define Word unsigned int
#endif



 /*
CONFIG1H : $300001 : 0x0028
CONFIG2L : $300002 : 0x0019
CONFIG2H : $300003 : 0x003C
CONFIG3H : $300005 : 0x00BE
CONFIG4L : $300006 : 0x0081
CONFIG5L : $300008 : 0x000F
CONFIG5H : $300009 : 0x00C0
CONFIG6L : $30000A : 0x000F
CONFIG6H : $30000B : 0x00E0
CONFIG7L : $30000C : 0x000F
CONFIG7H : $30000D : 0x0040


*/


const int MAX_LEN264;
unsigned int i,j,k,l,m,n;
unsigned char CRam1[MAX_LEN2];
unsigned char Ratio;


void Init_Hardware(void) ;
void CRLF1(void) ;
void Raz_Buffer(void) ;
void UART1_Write_CText(const char *txt);


void CRLF1()
{
 
UART1_Write(CR); UART1_Write(LF);
}

void UART1_Write_CText(const char *t1)
 { 
char cx;
  do
  { 
cx=*(t1++);
    if (
cx==0) break;
    
UART1_Write(cx);
    
Delay_us(50);
  }while(
cx>0);
}


void Init_Hardware()
{

  
PORTA 0x00;
  
ANSELA=0;
  
ANSELA.ANSA0=1;    //  analog input on Port RA0   voir page 154
  
ANSELA.ANSA1=1;    //  analog input on Port RA1
  
ANSELA.ANSA2=1;     //  analog input on Port RA2
  
TRISA 0b11101111 ;   // PORTA is RA0,1,2,3= analog input  ...  RA4  =Digital output   RA5= Input RTC force


  
ANSELB=0;
  
PORTB 0xFF;
  
TRISB 0xFF;  
  
CM1CON0=0;
  
CM2CON0=0;

  
PORTC=0;
  
ANSELC=0
  
TRISC=0xFF;
  
TRISC.TRISC0 1;  // DTH22 OWS  
  
TRISC.TRISC1 0;  // output to BT HC06 reset
                     // ou  Synchro_SQ50
  
TRISC.TRISC21;  // PWM output
  
TRISC.TRISC3 0;  // SCL I2C
  
TRISC.TRISC4 1;  // SDA I2C
  
TRISC.TRISC7 1;  // RX - UART1
  
TRISC.TRISC6 0;  // TX - UART1

  
SLRCON=0// standard rate for PORTA,B,C,D,E
 
}


void main() 
{
  
OSCCON.IRCF2=1//HFINTOSC - (16 MHz)
  
OSCCON.IRCF1=1;
  
OSCCON.IRCF0=1;
  
OSCCON.SCS1=1;    // choix config bit preponderant sur choix par OSSCON
  
OSCCON.SCS0=0;
  
OSCTUNE=0;
  
OSCTUNE.PLLEN=0;  // 1= avec PLL => 64Mhz ou 40Mhz   0 =sans PLL => 16Mhz

  
Init_Hardware() ;
  
  
UART1_Init(19200);
   for (
i=0;i<MAX_LEN2;i++) CRam1[i]=0;
  

  
Delay_ms(500);
  
UART1_Write(CLS);   // Erase screen terminal  :it is an option on Vbray Terminal!
  
Delay_ms(500);
  
CRLF1();
   
UART1_Write_CText("\r\nCas NORMAL  \r\n");
   for (
Ratio=0;Ratio<255;Ratio++)
   {
   
ByteToStr(Ratio,CRam1);
   
UART1_Write_Text(CRam1);   CRLF1();
   }
    
CRLF1();
   
Delay_ms(2000);
   
UART1_Write_CText("\r\nAvec mauvais choix (volontaire) de type de variable à transcrire\r\n");
    for (
Ratio=0;Ratio<255;Ratio++)
   {

   
// Short c'est pur un signed char !
   
ShortToStr(Ratio,CRam1);
   
UART1_Write_Text(CRam1);   CRLF1();
   }

   
CRLF1();
   
Delay_ms(2000);
   
UART1_Write_CText("\r\nLe cas K \r\n");
   for (
Ratio=0;Ratio<256;Ratio++)
   {
   
ByteToStr(Ratio,CRam1);
   
UART1_Write_Text(CRam1);   CRLF1();
   }
   
CRLF1();
   while(
1);
}
 
Aide toi, le ciel ou FantasPic t'aidera


Retourner vers « Langage C »

Qui est en ligne

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