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

Is this a C51 / uvision bug?

Hi all
Below is the result of some debugging. I have isolated some code from a bigger project and have put it into a stand-alone project.

I basically don't understand why I can do right bit-shifting and AND'ing on single line, when I can't do left bit-shifting and AND'ing on single line.

If it isn't a bug, then what have I missed?

I have included many comments to describe my problem

#include <ADUC832.H>
#include <string.h>

void main(void) {


char ascii[] = "MC";
unsigned char pdu[3];
int w=0, r=0, len;
char ch1, ch2, rr, rl;


 /*  This is what I want to do:

  while-loop run 1:
     1: Assign to var 'ch1':   ch1 = 'M' (= 0x4D = 0100 1101)
     2: Assign to var 'ch2':   ch2 = 'C' (= 0x43 = 0100 0011)
     3: Assign to var 'w'  :     w = 0
     4: OR together the following:
         ((ch1 >>(w%7))&0x7F) | ((ch2 <<(7-(w%7)))&0xFF);
     <=>     0100 1101        |       1000 0000
     <=>                  1100 1101
     <=>                     0xCD

  while-loop run 2:
     1: Assign to var 'ch1':   ch1 = 'C' (= 0x43 = 0100 0011)
     2: Assign to var 'ch2':   ch2 = 0x00
     3: Assign to var 'w'  :     w = 1
     4: OR together the following:
         ((ch1 >>(w%7))&0x7F) | ((ch2 <<(7-(w%7)))&0xFF);
     <=>     0010 0001        |       0000 0000
     <=>                  0010 0001
     <=>                     0x21

 */

len=strlen(ascii);

while (r<len) {

 // ------ First OR-part  -----------------------
 // -------Both versions below are OK  ----------

      // -- VER 1: OK
      //  ch1 = ascii[r];
      //  rr  = (w%7);
      //  ch1 = (ch1 >> rr) & 0x7F;

      // -- VER 2: OK
        ch1 = (ascii[r] >> (w%7)) & 0x7F;    // Bit-shifting and AND'ing
                                             // may be done in one line

 // ------  Second OR-part  -----------------------------
 //-------  Both versions below are NOT OK ??  ----------

      // -- VER 1: OK
        ch2 = ascii[r+1];
        rl = (7-(w%7));
        ch2 = (ch2 << rl) & ((char)0xFF);    // Bit shift and AND'ing can be
                                             // done in one line, IF type cast
                                             // is used - why?
      //  ch2 = ch2 & 0xFF;                  // If splitting into new line
                                             // type cast is not required?

      // -- VER 2: NOT OK
      //  ch2 = (ascii[r+1] << (7-(w%7))) & 0xFF;  // type cast doesn't help
      //  ch2 = ch2 & 0xFF;  // AND'ing must be on seperate line ?


    //----------------------------------------------------------------
    // IS THIS A BUG ??
    //----------------------------------------------------------------
    // Why can we bit-shift and do the AND'ing in a single line
    // for the first OR-part above, but cannot do it for the second
    // OR-part where bit-shifting and AND'ing must be on two seperate
    // lines ???
    //----------------------------------------------------------------

// ------ Do the actual OR'ing -------
        pdu[w]= (ch1 | ch2) ;

        if ((w%7)==6)
           r++;
        r++;
        w++;
    }
    pdu[w]=0; // terminator

    //----------------------------------------------------------------
    // Run to here in debugger and look at content of
    // local variable 'pdu'.
    // When using 'NOT OK' versions from above
    // pdu will contain {0x4D, 0x21, 0x00}
    // and not {0xCD, 0x21, 0x00} as the 'OK' versions
    // produce.
    //----------------------------------------------------------------

   while(1);

}

Parents Reply Children
  • so, all this runaround has been that reading 'the manual' (K&R) would agree that there is an inconsistency; whereas 'the manual (Keil C51) would state that there is not. The Keil manual staes that INTPROMOTE enables ANSI integer promotion rules. so WHERE in the KEIL manual does it state what you claim???

    Erik

  • The Keil manual staes that INTPROMOTE enables ANSI integer promotion rules.

    I think you must have actually looked something up in the manual!

    so WHERE in the KEIL manual does it state what you claim???

    No, I'm sure you can work it out for yourself. Clue: you were getting very warm.

  • so WHERE in the KEIL manual does it state what you claim???

    Have you found it yet?

  • no, it states the opposit6e, see 2 posts up

  • no, it states the opposit6e, see 2 posts up

    Go back and read the description again.

    Clue: You need to read more than the first sentence.

  • as I have said again and again, I have NO problem with how it works but it IS inconsistent, the fact it is 'documented' makes in NO LESS INCONSISTENT

    That there is even more heaped on the inconsistency, which I guess is what you refer to (sometimes integers are promoted, sometimes not condirtions a, b, c 'document' when it happens) does NOT IN ANY WAY make it ANY LESS inconsitemnt.

    I UTTERLY REFUSE to go along with your attempts to argue that because it is 'documented' there is no inconsistency.

    For that VERY REASON there is no way in hades you are going to make me quote the 'documented' inconsistencies.

    If you read through, you will find that I have never used the word 'wrong' but constantly the word 'inconsistent'.

    YES, I know which (double) inconsistency I ran into, am I going to look for logical explanation for something illogical, naah, I'll leave that to you. AN INCONSISTENCY IS AN INCONSISTENCY WHATEVER YOU SAY.

    Erik

  • For that VERY REASON there is no way in hades you are going to make me quote the 'documented' inconsistencies.

    I don't want you to quote anything. I want you to read and understand the manual. Do you now understand why your code behaves the way it does?

    If you read through, you will find that I have never used the word 'wrong' but constantly the word 'inconsistent'.

    Ok, I read through. Here are a few of the occasions you have used the word 'wrong':

    this (which is the same concatenated) GSloadCnt = (((GClwdt * GClhgt) / GX_ATT.FSLlin) / 2);
    gives the wrong result (zero)

    That I know enough to program in C and figure out what is wrong when it does not work is more than enough for me.

    What is more important: to have to 'figure out' a calculation that the debugger show has the wrong result

  • For that VERY REASON there is no way in hades you are going to make me quote the 'documented' inconsistencies.

    I don't want you to quote anything. I want you to read and understand the manual. Do you now understand why your code behaves the way it does?.

    I have understood that from my very first post "because the commpiler behaves in an inconsistent way" confound it DO YOU GET IT NOW?

    When the compiler behaves inconsistently, you apply (as shown) a workaround (in this case a typecast).

    If you read through, you will find that I have never used the word 'wrong' but constantly the word 'inconsistent'.

    Ok, I read through. Here are a few of the occasions you have used the word 'wrong':

    nitpick, can you understand this:

    "If you read through, you will find that I have never used the word 'wrong' as to the compilers behaviour but constantly the word 'inconsistent'"

    Erik

  • I have understood that from my very first post "because the commpiler behaves in an inconsistent way" confound it DO YOU GET IT NOW?

    The compiler behaves as documented in the manual. The only inconsistency is between that and your expectations. You have clearly not understood that from your very first post as you describe the behaviour as wrong.

    "If you read through, you will find that I have never used the word 'wrong' as to the compilers behaviour but constantly the word 'inconsistent'"

    No. In the quote below you describe the output of the compiled code as wrong:

    this (which is the same concatenated) GSloadCnt = (((GClwdt * GClhgt) / GX_ATT.FSLlin) / 2);
    gives the wrong result (zero)

    You wrote it - it really is pointless for you to deny it.