View previous topic :: View next topic |
Author |
Message |
guy
Joined: 21 Oct 2005 Posts: 297
|
odd behavior [solved] |
Posted: Tue Feb 13, 2018 9:59 am |
|
|
I am debugging a stable PIC24FJ64GA308 board with stable code, using MPLAB 8.92 and CCS 5.076 and picKit3.
I added a char, ch, which is read from an external eeprom. I put a breakpoint and it shows 0xFF as it should. But when I step over/into the code the expression if(ch==0xFF) somehow returns false and the compiler continues to the Else statement.
I double checked myself - mouse hover over ch shows 0xFF, watch window shows 0xFF or 255.
Take a look at the screenshot. Any ideas?!
https://ibb.co/ckqG37
----------------------------------------------------
#$(*%&! I changed the definition of ch from char to byte and it works ok. Can anyone explain this please? |
|
|
gaugeguy
Joined: 05 Apr 2011 Posts: 303
|
|
Posted: Tue Feb 13, 2018 12:08 pm |
|
|
The char definition would have defaulted to signed so -1 != 255 |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9226 Location: Greensville,Ontario
|
|
Posted: Tue Feb 13, 2018 12:49 pm |
|
|
hmm 'char' should be an unsigned int8, so 0-255 ( 0x00 to 0xff).
mind you there might be a compiler bug except now that I'n rereading the post...this is a 24 series PIC and them beasties are different than 'regular' PICs
sigh... so much for 'standards'....
how anyone can keep all this in their heads is beyond me
just wait until the 64 series PICs arrive...... |
|
|
guy
Joined: 21 Oct 2005 Posts: 297
|
|
Posted: Tue Feb 13, 2018 1:17 pm |
|
|
temtronic - that's why I have so much respect to CCS - building a compiler that supports all the parts
The 0xFF char is weird - it means that there is actual code being generated to distinguish between char and byte! I took a look at the disassembly but couldn't figure it out - the 16 bit assembly is beyond me. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19515
|
|
Posted: Tue Feb 13, 2018 1:47 pm |
|
|
Quite a few compilers make a char signed. This is why CCS specifically say to use byte for int8 data that must be unsigned.
The 'distinction' comes about, because the default type size in these PIC's is an int16. So you are comparing the negative character with 0x00FF. |
|
|
guy
Joined: 21 Oct 2005 Posts: 297
|
|
Posted: Tue Feb 13, 2018 2:12 pm |
|
|
I will never use char again! |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19515
|
|
Posted: Tue Feb 13, 2018 3:35 pm |
|
|
This is very much the reason why you will see a lot of the 'old hands' saying to use explicit types.
Load stdint.h, and use types like uint8_t.
Particularly if you move code onto other chips, it makes things massively easier. |
|
|
jeremiah
Joined: 20 Jul 2010 Posts: 1349
|
|
Posted: Thu Feb 15, 2018 1:37 pm |
|
|
guy wrote: | I will never use char again! |
It's ok to use char in the situations where a char is actually what you are using ('\n', '0', etc.) but you then have to remember to do any comparisons against chars as well. If you want to compare to the character 0xff, then you can do a couple different things:
Casting:
Code: |
if (c == (char)0xff){
}else{
}
|
character literal comparison:
Code: |
if (c == '\xff'){
}else{
}
|
You can see the code generated by different methods and versus the incorrect way:
Code: |
.................... char c = '\n';
....................
.................... if (c == '\xff'){
024A: MOV 802,W4
024C: XOR.B #FF,W4L
024E: BRA NZ,252
.................... }else{
0250: BRA 252
.................... }
....................
.................... if (c == (char)0xff){
0252: MOV 802,W4
0254: XOR.B #FF,W4L
0256: BRA NZ,25A
.................... }else{
0258: BRA 25A
.................... }
....................
.................... if (c == 0xff){ //this will fail!!!
025A: MOV.B 802,W0L
025C: SE W0,W0
025E: MOV #FF,W4
0260: CP W4,W0
0262: BRA NZ,266
.................... }else{
0264: BRA 266
.................... }
|
|
|
|
|