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
  • You offered me a choice of two things:

    What is more important: to have to 'figure out' a calculation that the debugger show has the wrong result (2 minutes) or fighting timing issue because of "fully using" C (days)?

    The first one is an example of how *not* to fix a problem caused by lack of knowledge of the programming language, the second is an example of how to fix a problem caused by poor program design.

    You then asked me to choose which is more important. Well, the important thing is to avoid getting into these sort of situations in the first place. Try taking a disciplined engineering approach to design and development instead.

    Rephrasing your answer

    Changing it to something completely different that suits you better would be a more accurate description...

    (The most important thing is to try and write correct, bug free code), by that you state that designing the program well is TOTALLY IRRELEVANT if your code is 'correct'.

    No, I don't state that.

    If you often spent days fighting timing issues I'd suggest that a little more planning before you start coding would be in order.

    and now you contradict what you said before. This could be my advice to someone else.

    No, I don't contradict what I said before.

    Will you please stop attributing false quotations? You've taken a statement I made, invented an alternative completely different statement, and then tell me I'm contradicting myself when in fact you have invented the statement I'm supposed to be contradicting? Grow up.

    Why don't you read the manual and find out how it works?

    already answered in my above post.
    I couldn't see your answer. Could you repeat it for me?

    you state "if something is inconsistent to you, assume it is the compiler that is designed inconsistent - I make no such assumption.

    Ok, I asked you to state your answer to the question:

    "Why don't you read the manual and find out how it works?"

    You have answered with yet another quotation from me that *you have modified to change the meaning*.

    No two cars, no two manuals, 4 windows in the same car

    I misunderstood. I thought you meant two or more cars.

    BULLSHIT

    Oh dear, more vulgarity.

    No, it is not, and I am friggin IMPRESSED that you can retain all the info in it.

    Oh dear, more vulgarity. Incidentally, I can't retain all the information. That's why I read the manual.

    Then, of course when your only interest is the programming language and not its appplication, that will make it easier.

    Once again, no matter how convenient the contrary would be for your argument, I *am* interested in both the programming language and its application. I also find that I can apply it much more effectively by reading the manual.

    It would save a lot of bandwidth if you would please refrain from these rather pathetic tactics of fabricating false quotations or 'adjusting' real ones.

Reply
  • You offered me a choice of two things:

    What is more important: to have to 'figure out' a calculation that the debugger show has the wrong result (2 minutes) or fighting timing issue because of "fully using" C (days)?

    The first one is an example of how *not* to fix a problem caused by lack of knowledge of the programming language, the second is an example of how to fix a problem caused by poor program design.

    You then asked me to choose which is more important. Well, the important thing is to avoid getting into these sort of situations in the first place. Try taking a disciplined engineering approach to design and development instead.

    Rephrasing your answer

    Changing it to something completely different that suits you better would be a more accurate description...

    (The most important thing is to try and write correct, bug free code), by that you state that designing the program well is TOTALLY IRRELEVANT if your code is 'correct'.

    No, I don't state that.

    If you often spent days fighting timing issues I'd suggest that a little more planning before you start coding would be in order.

    and now you contradict what you said before. This could be my advice to someone else.

    No, I don't contradict what I said before.

    Will you please stop attributing false quotations? You've taken a statement I made, invented an alternative completely different statement, and then tell me I'm contradicting myself when in fact you have invented the statement I'm supposed to be contradicting? Grow up.

    Why don't you read the manual and find out how it works?

    already answered in my above post.
    I couldn't see your answer. Could you repeat it for me?

    you state "if something is inconsistent to you, assume it is the compiler that is designed inconsistent - I make no such assumption.

    Ok, I asked you to state your answer to the question:

    "Why don't you read the manual and find out how it works?"

    You have answered with yet another quotation from me that *you have modified to change the meaning*.

    No two cars, no two manuals, 4 windows in the same car

    I misunderstood. I thought you meant two or more cars.

    BULLSHIT

    Oh dear, more vulgarity.

    No, it is not, and I am friggin IMPRESSED that you can retain all the info in it.

    Oh dear, more vulgarity. Incidentally, I can't retain all the information. That's why I read the manual.

    Then, of course when your only interest is the programming language and not its appplication, that will make it easier.

    Once again, no matter how convenient the contrary would be for your argument, I *am* interested in both the programming language and its application. I also find that I can apply it much more effectively by reading the manual.

    It would save a lot of bandwidth if you would please refrain from these rather pathetic tactics of fabricating false quotations or 'adjusting' real ones.

Children
  • I give up

    Jack, you go read your manual. I will write some quality code, that may not be 'intricate' but will be fully functional with much concern for not overloading the processor by "fully using the C language'.

    If you want to, go ahead and tell another outright lie, re my porogramming skills, which you have absolutely no idea about - that one intricacy of C to you is consistent and to me not, does not make you any better, just makes you a gospel reader.

    You keep on, there is evidently no other way to shut you up than ignoring you.

    Erik

  • I will write some quality code

    You've demonstrated that you use the 'change it until it appears to work' coding technique rather than the 'learn why it didn't work, rewrite it properly and avoid making the same mistake again' technique. If you think that the former technique will result in quality code you are sadly mistaken.

    that may not be 'intricate' but will be fully functional with much concern for not overloading the processor by "fully using the C language'.

    You are still confusing 'correct code' with 'badly designed code'. You seem unable to understand that reading the manual to learn how language constructs work does not mean that you will be unable to write code to target a specific platform.

    If you want to, go ahead and tell another outright lie re my porogramming skills, which you have absolutely no idea about

    You have posted the evidence yourself on this very forum!

    that one intricacy of C to you is consistent and to me not, does not make you any better, just makes you a gospel reader.

    Look, it's quite simple. If you read the manual you learn how the tools work. It doesn't make you a 'gospel reader', but it does allow you to use the tools better than someone who refuses to learn. Why anyone would disagree with this is beyond me, but I'm sure you'll have some sort of crazy explanation for it.

    You keep on, there is evidently no other way to shut you up than ignoring you.

    I'm glad to see you finally realise your position is untenable.

  • avoid making the same mistake again'
    I DO "avoid making the same mistake again" I am no imbecile and when I learn somethnig (here that K&R are inconsistent in this case) I DO retain it.

    If you want to, go ahead and tell another outright lie, re my porogramming skills, which you have absolutely no idea about - that one intricacy of C to you is consistent and to me not, does not make you any better, just makes you a gospel reader.

    this will respond to any further post from you

    Erik

  • I DO "avoid making the same mistake again"

    The example problem and 'solution' you posted in this thread shows that you did not learn from your mistake. If you had identified *why* the code compiled the way it did rather than changing it around until it worked then you *would* have learned something which would help you avoid making the same mistake again.

    I am no imbecile and when I learn somethnig (here that K&R are inconsistent in this case) I DO retain it

    Why are you accusing K&R of being 'inconsistent' now?

  • Why are you accusing K&R of being 'inconsistent' now?
    because they are!!

    if you document an inconsistency that does not make it any less an inconsistency.

    You keep harping 'read the manual', how can 'reading the manual' and seeing an inconsistency 'documented' make it any less an inconsitency?

    You keep harping "because it is documented it is not an inconsistency" BALONEY!!!

    Erik

  • Erik, you'll have to face it: what you called an "inconsistency" is not actually one. That's the whole problem. One part of the problem is that you misuse the word itself. Inconsistency as a predicate cannot be applied to a single entity. It takes two things so they can be inconsistent to each other.

    I explained to you a long way upthread what the actual problem was, and that explanation can be backed up every step of the way by K&R. You posted two code snippet you believed were equivalent, and stated that Keil was wrong for giving different results for them. But in fact, strictly according to K&R, the two snippets weren't equivalent to begin with, and that's all the explanation it took to explain the difference.

    So the only inconsistency anywhere around here is between your expectations and the facts. And, no matter how much that hurts your self-image, Erik, the fact remains: that's neither K&R's fault, nor Keil's. It's entirely the fault of your expectations.

    The reason those expectations are at odds with the documented behaviour is because you consider yourself beyond reading manuals. The case at hand has proved you wrong on that count.

    And for somebody so vociferously protesting his professionalism, your reaction to that discovery has been really rather disappointingly unprofessional. It's been mostly equivalent to that of a five-year old stomping his foot and shouting "Not so!" at the top of his lungs, mixed with rather excessive amounts of foul language. You didn't really believe that calling people "Cidiot" was going to earn credit to your side of the argument, did you?

    What both of you guys really need is a cool-down. As in: no posting here at all, for at least one full week.

  • Erik, you'll have to face it: what you called an "inconsistency" is not actually one. That's the whole problem. One part of the problem is that you misuse the word itself. Inconsistency as a predicate cannot be applied to a single entity. It takes two things so they can be inconsistent to each other.
    I AM referring to two things both having a short as the result, one 'autopromotes', another does not. If two cases with the same size of the result react diffrent that IS inconsistent.

    I explained to you a long way upthread what the actual problem was, and that explanation can be backed up every step of the way by K&R.
    You keep harping "if it is documented, it is not inconsistent" BALONEY

    And for somebody so vociferously protesting his professionalism, your reaction to that discovery has been really rather disappointingly unprofessional.
    my SOLE 'reaction' has been to your REFUSAL to accept that it is inconsistent, and your eternal hammring that an inconsistencty that is 'documented' is not an inconsistency. I am aware of how it works, that it is inconsistent has nothing whatsoever to do with whatever the manual may say.

    Erik

  • "If two cases with the same size of the result react diffrent that IS inconsistent."

    Size isn't the only thing to consider.

    "... that it is inconsistent has nothing whatsoever to do with whatever the manual may say."

    Well, it really does because the manual tells you how operand conversion are applied, factoring in both size and sign. So if we add the detail of how C performs operand conversions to your code fragments, one can see that foo1() and foo3() below are equivalent. Comparing foo1() and foo2() below shows inequality, not inconsistency. Hopefully that has made one of the things people are arguing with you about clearer.

    typedef unsigned char U8;
    typedef unsigned short U16;
    
    U8  GClwdt;
    U8  GClhgt;
    U16 GSloadCnt;
    struct {
        U8 FSLlin;
    } GX_ATT;
    
    void foo1(void)
    {
        GSloadCnt = GClwdt  * GClhgt;
        /* U16    = (int)U8 * (int)U8 */
    
        GSloadCnt = GSloadCnt / GX_ATT.FSLlin;
        /* U16    = U16       / (U16)U8 */
    
        GSloadCnt = GSloadCnt / 2;
        /* U16    = U16       / (U16)int */
    }
    
    void foo2(void)     /* "this (which is the same concatenated)".  IS IT REALLY? */
    {
        GSloadCnt =      (((GClwdt  * GClhgt ) / GX_ATT.FSLlin) / 2);
        /* U16    = (U16)((((int)U8 * (int)U8) / (int)U8      ) / int); */
    }
    
    void foo3(void)
    {
        GSloadCnt = ((     (GClwdt  * GClhgt ) / (U16)GX_ATT.FSLlin) / 2);
        /* U16    = (((U16)((int)U8 * (int)U8) / (U16)U8           ) / (U16)int); */
    }
    
    
    

  • below shows inequality, not inconsistency

    you can keep your verbiage with my blessing, just acceot that it is yours instead of insisting that i accept it. Since every statement figures out a short it is inconsistent that they do not work on the longest thing in the equation.

    because the manual tells you
    here we go again, documenting an inconsistency does NOT make it anything else

    Erik

  • Oh brother! You didn't even look at the differences to see that they are flat out obviously different -- what effect the presence and absence of your single (U16) had in other subexpressions. I honestly though that boiling how the conversions are performed to a low gravy would benefit you, but you're just a hopeless case, I'm afraid -- pure and simple.

    You can lead people to knowledge, but you can't make them think.

  • I AM referring to two things both having a short as the result, one 'autopromotes', another does not.

    The fact those code samples eventually stuff the results into a short is utterly irrelevant. Intermediate results are never smaller than int, and that's what broke the supposed equivalence of your code samples. In particular, an operation on u8 values, without any casts, like in those samples, produces a result of type signed int. Not short, not unsigned: signed int. Casting one of the u8 operands to u16, i.e. unsigned int, changes that. Storing one of the intermediate results into a u16 variable is equivalent to an (u16) cast.

    Consistency means that equivalent input should produce equivalent results. But your code samples are not equivalent to start with, and thus unusable in an argument over consistency.

    You keep harping "if it is documented, it is not inconsistent" BALONEY
    [...]your eternal hammring

    Are you so deep in tantrum-throwing mode that you don't even look who wrote a posting now, Erik? Or what else gives you an excuse to call total of 2 postings by me in this entire thread, 2 weeks apart from each other, an "eternal hammering"?

    Looks like I have to repeat myself: cool down, man.

  • GSloadCnt = (((GClwdt * GClhgt) / GX_ATT.FSLlin) / 2);
    U16 U8=160 U8=16 U8=2

    even if, as you say "Intermediate results are never smaller than int, and that's what broke the supposed equivalence of your code samples. In particular, an operation on u8 values, without any casts, like in those samples, produces a result of type signed int."
    that should not produce a result of zero.

    You keep harping "if it is documented not you, but Jack in each and every post has stated things to that effect, if not an exact quote.

    Ab=nyhow, regardless of consistency, if intermidiat6e are 'signed int' the resullt should not be zero.

    Erik

  • ou got?erik malund

    somehow a partial snuck into my name, sorry

    realizing I should have used 'pre' here it is again

    GSloadCnt = (((GClwdt * GClhgt) / GX_ATT.FSLlin) / 2);
    U16            U8=160 U  8=16      U8=2
    

    Erik

  • that should not produce a result of zero.

    Yes, it should.

    How do I know?

    I read both manuals.

  • Hans-Bernhard Broeker Posted
    an operation on u8 values, without any casts, like in those samples, produces a result of type signed int.
    by that

    GSloadCnt = (((GClwdt * GClhgt) / GX_ATT.FSLlin) / 2);
    U16            U8=160   U8=16      U8=2
    is calculated as
    GSloadCnt = (((GClwdt * GClhgt) / GX_ATT.FSLlin) / 2);
    U16            S16=160  S16=16    S16=2
    

    so, you and Hans-Bernhard evidently do not read the same book since you post:
    Yes, it should.
    Erik