This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Wrong use of unsigned compare (BHI instead of BGT)

Please have a look at the following code examples (3 different versino to write i > imax-5):

char ac[5];
int i= 0;
int imax= 1;

if( i < imax && i > imax - siezof(ac)){
  ... all ok code 1 ...
}

if( i < imax && i > imax - 5){
  ... all ok code 2 ...
}

if( i < imax && i > imax - (unsigned int)5){
  ... all ok code 3 ...
}

Here every C compiler I know would branch into "all ok code" 1, 2, 3 (making no difference between these 3 compare situations). But Keil C compiler branches only into "all ok code" 2. The reason is, that is prefers to use the "unsigned compare" command BHI for case 1 and 3 - this is really bizarre. Instead of the correct "signed compare" BGT (as it is used correctly for case 2). Is there any possibility to avoid this, maybe some very hidden compiler switch? (or any reason, why this should make sense - especially in a 32 bit processor where the int range is tremendeously wide?).

It looks, as if "signed int - unsigned int" is handled as "unsigned int", also compare between "signed int" and "unsigned int" is handled like compare between two "unsigned int". This preferential usage of "unsigned int" is really hard to understand (see my comment above).

As it is of course not easy for Keil, to change this "unsigned compare preference" (as it possibly would lead to unexpected code changes for existing code), could Keil please consider to add another compiler switch "Prefer signed compare" (or something equivalent, maybe there where you now also have the compiler switch "Plain char is signed" ...)?

PS: I use ARM Cortex M4, STM32F4 family.

Parents
  • Here every C compiler I know would branch into "all ok code" 1, 2, 3 (making no difference between these 3 compare situations).

    In that case all C compilers you've known before would have been wrong.

    This preferential usage of "unsigned int" is really hard to understand (see my comment above).

    Even if that's the case --- this preference is, for all practical intents and purposes, the law in C programs. Mixing signed and unsigned numbers in the same expression correctly takes knowledge of the actual rules of C --- trying "common sense" instead will get you in trouble.

    Sorry, but it's really your source that's at fault here, so that's what you need to fix. There is absolutely no reason for Keil to break their compiler to work with broken code like you're proposing.

Reply
  • Here every C compiler I know would branch into "all ok code" 1, 2, 3 (making no difference between these 3 compare situations).

    In that case all C compilers you've known before would have been wrong.

    This preferential usage of "unsigned int" is really hard to understand (see my comment above).

    Even if that's the case --- this preference is, for all practical intents and purposes, the law in C programs. Mixing signed and unsigned numbers in the same expression correctly takes knowledge of the actual rules of C --- trying "common sense" instead will get you in trouble.

    Sorry, but it's really your source that's at fault here, so that's what you need to fix. There is absolutely no reason for Keil to break their compiler to work with broken code like you're proposing.

Children