CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

const bit array problem

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
nurquhar



Joined: 05 Aug 2006
Posts: 149
Location: Redditch, UK

View user's profile Send private message Visit poster's website

const bit array problem
PostPosted: Fri Mar 08, 2013 12:54 pm     Reply with quote

Question
My assumption is that this should produce a string of "X.X.X.X.".
Code:

void test()
{
   const int1 klm[] = {1,0,1,0,1,0,1,0} ;
   int i ;

   for(i = 0 ; i < 8 ; i++) {
      if(klm[i]) {
         usb_cdc_putc('X') ;
      } else {
         usb_cdc_putc('.') ;
      }
   }
   printf(usb_cdc_putc, "\r\n") ;
}



However I actualy get "XXXXXXXX" Exclamation

Is there any reason I can't have a const bit array ?

The code works corretly if i change "int1 klm" to be "int8 klm"

The PIC is 18F27J53 and CCS PCH C Compiler, Version 4.133
Ttelmah



Joined: 11 Mar 2010
Posts: 19520

View user's profile Send private message

PostPosted: Fri Mar 08, 2013 1:33 pm     Reply with quote

There is a problem with int1 variables not automatically 'casting' in certain cases.
Now the behaviour of certain things changed with later compilers. Historically the test:

if(klm[i])

Translated as "if klm[i] does not equal zero". With an int1 you'd expect this to comfortably translate as true/false. However the ANSI test changed the meaning, and it now evaluates as "if klm[1] and 1 does not equal zero". Again you'd expect this to work, but in fact the int1 type mishandles this. If you explicitly cast the int1 to int8, it'll then work.

This has been reported to CCS, and they claim it will be fixed in the next release.

As a comment, you do realise how much code space this will use?. If you have several thousand bits needing storage, then worth doing, but for small arrays, the int8 code will be a lot smaller.

Best Wishes
nurquhar



Joined: 05 Aug 2006
Posts: 149
Location: Redditch, UK

View user's profile Send private message Visit poster's website

PostPosted: Sat Mar 09, 2013 3:29 am     Reply with quote

I tried both casting and copying int1 to int8 and result the same. ie both of these don't work :

Code:

void test()
{
   const int1 klm[] = {1,0,1,0,1,0,1,0} ;
   int i ;

   for(i = 0 ; i < 8 ; i++) {
      if((int8)klm[i]) {
         usb_cdc_putc('X') ;
      } else {
         usb_cdc_putc('.') ;
      }
   }
   printf(usb_cdc_putc, "\r\n") ;
}

Code:

void test()
{
   const int1 klm[] = {1,0,1,0,1,0,1,0} ;
   int i ;
   int8 x ;

   for(i = 0 ; i < 8 ; i++) {
      x = klm[i] ;
      if(x) {
         usb_cdc_putc('X') ;
      } else {
         usb_cdc_putc('.') ;
      }
   }
   printf(usb_cdc_putc, "\r\n") ;
}


So given I am using V4.133 which is from about June 2012, and its not been fixed in the last half dozen or more updates, is it ever likely to be fixed now V5 is around the next corner Question

Its not then end of the world for my app as I am just using the 18F27J53 to develop some code on and then port it to a 16F886 (the ultimate target has used the ICD pins as outputs). I was using const bit array as substitue for not having EEPROM on the dev part. When the app gets ported to the 886 the bit arrays will be access from RAM after a copy from EEPROM. So it should all work there.

I did also tried changing "const" to "rom" but program got hugh and crashed somewhere in the wild blue yonder. So I quickly changed it back to const.
nurquhar



Joined: 05 Aug 2006
Posts: 149
Location: Redditch, UK

View user's profile Send private message Visit poster's website

PostPosted: Sat Mar 09, 2013 3:54 am     Reply with quote

Ok I tried another test :

Code:
void test2()
{
   const int1 klm[] = {1,0,1,0,1,0,1,0} ;
   int1 cp[] = {1,0,1,0,1,0,1,0} ;
   int i ;
   int8 x ;

   for(i = 0 ; i < 8 ; i++) {
      x = klm[i] ;
      printf(usb_cdc_putc, "%02x ", x) ;
   }
   printf(usb_cdc_putc, "\r\n") ;

   for(i = 0 ; i < 8 ; i++) {
      x = cp[i] ;
      printf(usb_cdc_putc, "%02x ", x) ;
   }
   printf(usb_cdc_putc, "\r\n") ;
}


Result :
01 01 01 01 01 01 01 01
55 2a 95 4a a5 52 a9 54


So the const bit array can't work, code allways gives same result for each element of the array. For the RAM bit array bit 0 is as expected. ie if use x = cp[i] & 0x01 then should see 01 00 01 00 01 00 01 00.
Ttelmah



Joined: 11 Mar 2010
Posts: 19520

View user's profile Send private message

PostPosted: Sat Mar 09, 2013 5:02 am     Reply with quote

No, your are still having the same problem.
You have to force the actual test to be done on an int8, and use the correct logic. Currently all you are doing is effectively converting the result of the test to int8 The test is 'implicit' before you get as far as the cast.

So you need:

if((int8)klm[i]!=0)

It does work.

Best Wishes
nurquhar



Joined: 05 Aug 2006
Posts: 149
Location: Redditch, UK

View user's profile Send private message Visit poster's website

PostPosted: Sat Mar 09, 2013 7:16 am     Reply with quote

Dear Ttelmah

Thanks for the explicit code but, Nope ! Still don't work that way either, unless I am being dense. When you say it works, have you tested it ? If so which version gave the correct result ?

I changed code as you suggested to be :
Code:
void test()
{
   const int1 klm[] = {1,0,1,0,1,0,1,0} ;
   int i ;

   for(i = 0 ; i < 8 ; i++) {
      if((int8)klm[i]!=0) {
         usb_cdc_putc('X') ;
      } else {
         usb_cdc_putc('.') ;
      }
   }
   printf(usb_cdc_putc, "\r\n") ;
}


Result is still XXXXXXXX Shocked

Here is the relavant list so you can compare to your output :
Code:
CCS PCH C Compiler, Version 4.133, 61227               09-Mar-13 13:02

.................... void test()
.................... {
....................    const int1 klm[] = {1,0,1,0,1,0,1,0} ;
....................    int i ;
.................... 
....................    for(i = 0 ; i < 8 ; i++) {
01306:  MOVLB  1
01308:  CLRF   xC3
0130A:  MOVF   xC3,W
0130C:  SUBLW  07
0130E:  BNC   1360
....................       if((int8)klm[i]!=0) {
01310:  CLRF   xC5
01312:  MOVFF  1C3,1C4
01316:  MOVFF  1C3,00
0131A:  RRCF   00,F
0131C:  RRCF   00,F
0131E:  RRCF   00,F
01320:  MOVLW  1F
01322:  ANDWF  00,F
01324:  MOVF   00,W
01326:  MOVLB  0
01328:  CALL   0262
0132C:  MOVWF  01
0132E:  MOVLW  07
01330:  ANDWF  00,F
01332:  BCF    FD8.0
01334:  RLCF   01,F
01336:  INCF   00,F
01338:  BCF    FD8.0
0133A:  RRCF   01,F
0133C:  DECFSZ 00,F
0133E:  BRA    1338
01340:  BTFSS  01.0
01342:  BRA    1350
....................          usb_cdc_putc('X') ;
01344:  MOVLW  58
01346:  MOVLB  1
01348:  MOVWF  xC4
0134A:  MOVLB  0
0134C:  RCALL  12F2
....................       } else {
0134E:  BRA    135A
....................          usb_cdc_putc('.') ;
01350:  MOVLW  2E
01352:  MOVLB  1
01354:  MOVWF  xC4
01356:  MOVLB  0
01358:  RCALL  12F2
....................       }
....................    }
0135A:  MOVLB  1
0135C:  INCF   xC3,F
0135E:  BRA    130A
....................    printf(usb_cdc_putc, "\r\n") ;
01360:  MOVLW  0D
01362:  MOVWF  xC4
01364:  MOVLB  0
01366:  RCALL  12F2
01368:  MOVLW  0A
0136A:  MOVLB  1
0136C:  MOVWF  xC4
0136E:  MOVLB  0
01370:  RCALL  12F2
.................... }
01372:  GOTO   1552 (RETURN)
Ttelmah



Joined: 11 Mar 2010
Posts: 19520

View user's profile Send private message

PostPosted: Sat Mar 09, 2013 8:50 am     Reply with quote

I'd guess the problem is 4.133 then.
The nearest I have is 4.137, and on this it works. It also works on a couple of older versions, but wouldn't work on 4.118.
There are two separate 'issues' older compilers had problems with int1 arrays in general. It was a 'feature' that appeared around the late 4.0xx area, worked, then didn't, then worked again. Possible that 4.133 was one of the ones where it didn't....
The second issue is that on the latest few releases there are this peculiar type casting issue with some operations. It behaves as if the int1, is 'half way' to an int8. Certain operations seem to treat it as an int1, but others treat it as an int8, and in some cases maths is applied to the int8 'container', not to the required bit. This causes some major oddities like the result sometimes being different if you test:
Code:

  int8 test_val=1;
  int1 bit1=0,bit=1;

  if (test_val==bit)

  //gives different results to:
 
  if (bit==test_val)

In the former case, it sees that 'test_val' is an int8, decodes 'bit' and propagates this into a byte and tests. In the second, it compares the bytes and decides they are different.....

I've sent a 'suite' of demo test codes to CCS, covering about a dozen operations where variations on this oddity appears, and several weeks ago, they said they would be fixed. Perhaps this is one reason why 4.141 is so slow coming.....

Yes, I did test it in 4.137, and on this it merrily generates X.X.X.X.

Best Wishes
nurquhar



Joined: 05 Aug 2006
Posts: 149
Location: Redditch, UK

View user's profile Send private message Visit poster's website

PostPosted: Sat Mar 09, 2013 9:05 am     Reply with quote

Dear Ttelmah

Thanks for testing this, atleast I know know its a compiler bug. However even paying for another maintenance update is not going to fully solve it for me. Makes sense to hold onto my money until I see a compiler update with load of bit array fixes. Rolling Eyes
Ttelmah



Joined: 11 Mar 2010
Posts: 19520

View user's profile Send private message

PostPosted: Sat Mar 09, 2013 9:39 am     Reply with quote

As a comment, you don't have the array access code there.
To see this, you need to 'rem' out the #nolist at the top of the processor include file. The call to 262, is the actual code to access the array element. The code divides to address required by 8 (the RRCF instructions), and then calls this function to read program memory. It then tests the bit in the returned value.

Best Wishes
nurquhar



Joined: 05 Aug 2006
Posts: 149
Location: Redditch, UK

View user's profile Send private message Visit poster's website

PostPosted: Sat Mar 09, 2013 10:53 am     Reply with quote

Dear Ttelmah

See list output below :
FYI, I also found to test for Non Zero in RAM bit arrays I need to use "if((int8)xyz[i]&1)"



Code:
.................... void test()
.................... {
....................    const int1 klm[] = {1,0,1,0,1,0,1,0} ;
....................    int i ;
.................... 
....................    for(i = 0 ; i < 8 ; i++) {
*
0190E:  MOVLB  1
01910:  CLRF   xAA
01912:  MOVF   xAA,W
01914:  SUBLW  07
01916:  BNC   1968
....................       if((int8)klm[i]!=0) {
01918:  CLRF   xAC
0191A:  MOVFF  1AA,1AB
0191E:  MOVFF  1AA,00
01922:  RRCF   00,F
01924:  RRCF   00,F
01926:  RRCF   00,F
01928:  MOVLW  1F
0192A:  ANDWF  00,F
0192C:  MOVF   00,W
0192E:  MOVLB  0
01930:  CALL   02AA
01934:  MOVWF  01
01936:  MOVLW  07
01938:  ANDWF  00,F
0193A:  BCF    FD8.0
0193C:  RLCF   01,F
0193E:  INCF   00,F
01940:  BCF    FD8.0
01942:  RRCF   01,F
01944:  DECFSZ 00,F
01946:  BRA    1940
01948:  BTFSS  01.0
0194A:  BRA    1958
....................          usb_cdc_putc('X') ;
0194C:  MOVLW  58
0194E:  MOVLB  1
01950:  MOVWF  xC6
01952:  MOVLB  0
01954:  RCALL  1356
....................       } else {
01956:  BRA    1962
....................          usb_cdc_putc('.') ;
01958:  MOVLW  2E
0195A:  MOVLB  1
0195C:  MOVWF  xC6
0195E:  MOVLB  0
01960:  RCALL  1356
....................       }
....................    }
01962:  MOVLB  1
01964:  INCF   xAA,F
01966:  BRA    1912

Code:

002AA:  CLRF   FF7
002AC:  ADDLW  BE
002AE:  MOVWF  FF6
002B0:  MOVLW  02
002B2:  ADDWFC FF7,F
002B4:  MOVLW  00
002B6:  MOVWF  FF8
002B8:  TBLRD*+
002BA:  MOVF   FF5,W
002BC:  RETURN 0
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Sat Mar 09, 2013 3:35 pm     Reply with quote

Ttelmah wrote:
Perhaps this is one reason why 4.141 is so slow coming.....
Did you notice v4.141 was released March 6?
Quote:
Recent changes include:
4.141 Various chip specific built in functions fixes have been made
4.141 A problem on some chips with strings in #rom is fixed
4.141 A PIC24 problem with some bit arrays is fixed
Strange that bit array problems are mentioned for the PIC24 only, but we have seen before that the release notes are far from complete. As Ttelmah seems to have a complete test suite he can confirm the problems to be solved or not.
Ttelmah



Joined: 11 Mar 2010
Posts: 19520

View user's profile Send private message

PostPosted: Sat Mar 09, 2013 3:40 pm     Reply with quote

I wouldn't say 'complete', but 'medium comprehensive'.... Smile

I hadn't noticed it. I had looked a few days ago. Normally if you have a ticket 'lodged' they tell you. I'll do some gentle trying when I get a chance. The real question (as always), is what else goes wrong?.

Best Wishes
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Sat Mar 09, 2013 4:19 pm     Reply with quote

Instead of checking the website on a regular interval I've registered myself to be notified when a new compiler update is available (bottom right of the page is an option "Get email notifications for new versions").
Ttelmah



Joined: 11 Mar 2010
Posts: 19520

View user's profile Send private message

PostPosted: Tue Mar 12, 2013 1:54 am     Reply with quote

I can confirm that 4.141, does correctly handle this. Now going to test some of the more complex problems I found.

It appears to be handling all the problems I had found. Smile

Only problem is that as FvM has already pointed out, they may have broken some other bits.....

Best Wishes
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group