LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

Labwindows CVI bug, ANSI c characters

I noticed a VERY annoying bug in LabWindows/CVI v7.1.1 having to do with comparisons between ANSI characters, that is characters with a higher code than 127  (Hex: 7F).

Take this sample program

if (0xA0 == 0xA0)
    printf("sucess!");
else
    printf("failure");

You would expect this program would printt success, and it does.

Try this now

char c = 0x7F

if (c== 0x7F)
    printf("sucess!");
else
    printf("failure");

Again success is printed as expected

Now finally the bug - occurs when making comparisons with c>7F

char c = 0xA0

if (c== 0xA0)
    printf("sucess!");
else
    printf("failure");

This prints failure. The error is extremely annoying for me as I am sending/receiving commands over TCP/IP and this results in me not being able to parse the MSB in each byte. Anyone had this problem is there a fix?

Thanks,

Dave




 


0 Kudos
Message 1 of 7
(3,687 Views)

It is not so much a bug in CVI as it is an ambiguous part of the c language.  In this case the comparison is not done at the level of char but is promoted to something more native to the processor architecture.  0xA0 and char A0 can be promoted differently due to sign extension.  Sign extension converts A0 to 0xFFA0  For this comparison to work the way you expect and to be more portable try this

char c = 0xA0;

if ((c&0x0FF)== 0x0A0)
    printf("sucess!");
else
    printf("failure");

Message Edited by mvr on 07-10-2006 02:27 PM

0 Kudos
Message 2 of 7
(3,682 Views)
Isn't is simpler to define c as unsigned char? Smiley Wink


Proud to use LW/CVI from 3.1 on.

My contributions to the Developer Community
________________________________________
If I have helped you, why not giving me a kudos?
Message 3 of 7
(3,672 Views)
Works Great.
Thanks a lot mvr, this is really going to make my life much easier.
0 Kudos
Message 4 of 7
(3,669 Views)

Original reply:

Another thing you can do is use a type cast on the value you are comparing against. I prefer this approach because then you are comparing apples to apples and sign extension is a non-issue because both values will be treated the same in any sort of conversion.

char c = 0xA0;

if (c == (char) 0xA0)
    printf("sucess!");
else
    printf("failure");

EDIT: As Roberto suggests, declaring c as unsigned char will prevent the sign extension when the char is promoted to int for the comparison. I'm actually not sure my recommendation above will work because I am unsure if the compiler will also sign-extend the literal value (I suppose I could test it out).

Anyway, the approach below will definitely work (and it has the advantage of not performing an unnecessary bitwise and operation):

unsigned char c = 0xA0;

if (c == (unsigned char) 0xA0)
    printf("sucess!");
else
    printf("failure");

 

Message Edited by MJF on 07-10-2006 12:57 PM

Martin Fredrickson
Test Engineer

Northrop Grumman
Advanced Systems and Products
San Diego, CA 92128
0 Kudos
Message 5 of 7
(3,668 Views)
I've run into this in the past, 99% of complilers will define char as signed, Just like int, short, and long as it should be. There are a few than don't but they are far and few between. The problem is not with the signedness of char but rather the comparison in the if statement. You are compariing a signed and unsigned number. Numbers specified in hex are treated as unsigned unless otherwise casted.

When the compliler generates code for

char c;

c=0xa0;

if( c == 0xA0 )
...

it treats c as a signed character (byte) but extends it to a signed integer to match the 0xa0 as an unsigned integer. So the value in c (-96 two's complement of 0xa0) is not equal to 0xa0 (160)

However, if you type cast 0xa0 to a char then you will get the correct comparison. Think someone suggested that. But if you type cast c to an integer you still get -96 becase the system uses signed extensions and adds in the extra 1's in the high order bits.

When in doubt use unsigned numbers they ALWAYS compare corretly. 😉

Regards,
Brian G Shea
QorTek Inc.


Brian G Shea
0 Kudos
Message 6 of 7
(3,652 Views)

Or even better, compare chars to chars. Use the hexadecimal character notation below. This will definitely be the most portable. I'm not sure why I didn't think of this when I posted yesterday.

char c = '\xA0';

if (c == '\xA0')
    printf("sucess!");
else
    printf("failure");

 

 

Martin Fredrickson
Test Engineer

Northrop Grumman
Advanced Systems and Products
San Diego, CA 92128
0 Kudos
Message 7 of 7
(3,616 Views)