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);

}

  • you sure are. The Cidiots preach using malloc, function pointers, switch etc regardless of the platform and compiler

    So you think that writing correct 'C' makes one a 'Cidiot'?

    but what makes you think my bug free code is not correct

    I don't. I think that your incorrect code is probably not bug free.

    I'm not going to waste time answering your other comments which seem to confuse being an incompetent programmer with writing correct code.

    or is it because I do not suppress warnings, but fix them?

    You've already demonstrated that your idea of fixing something is to change it until it appears to work without understanding why. 'Fix' and 'get rid of by changing stuff' are not synonymous. The latter approach is no better than suppressing the warning.

    I am rally amazed that you can think that the more than a million units running with my code in them without complaints are an indication that they most probably aren't bug free

    Given your cavalier approach to engineering I think I'm more amazed than you. I guess that either your kit does pretty trivial stuff or you got lucky.

    I notice that as usual you avoid answering points where even you realise your position is untenable, but please answer this question for me:

    Why do you refuse to read the one document that would explain to you definitively how all the parts of the 'C' language that you use actually work? (Note that this would be quite a small subset of the document).

  • So you think that writing correct 'C' makes one a 'Cidiot'?
    absolutely not, just that your opinion of what "correct 'C'" (bug free is not good enought) does.

    but what makes you think my bug free code is not correct
    I don't. I think that your incorrect code is probably not bug free.

    1) my code is NOT 'incorrect' just not 'fancy'
    2) it IS bug free

    I'm not going to waste time answering your other comments which seem to confuse being an incompetent programmer with writing correct code.
    you may very7 well be more 'competent' than me in the finer nuances of C but I will bet that compared to me you are GROSSLY 'incompetent' in '51 C as shown by you pushing all comments about timing aside.

    You've already demonstrated that your idea of fixing something is to change it until it appears to work without understanding why.
    where do you get the "without understanding why" from. Do you really believe that when something does not work and I solve it I learn NOTHING?. Re. "appears to work", that is NEVER the case, if I am in any doubt, I look at the generated assembler. That, of course, is beneath the elevated status of any Cidiot.

    Given your cavalier approach to engineering I think I'm more amazed than you. I guess that either your kit does pretty trivial stuff or you got lucky.
    "cavalier approach to engineering" that is offensive what about your cavalier approach to program design compared to your approach to coding where you concentrate instead of where it matters?

    Why do you refuse to read the one document that would explain to you definitively how all the parts of the 'C' language that you use actually work?
    I do not 'refuse' why would I, i have a copy. I just do not see why asking in a forum is so terrible and show 'incompetence'. Now one question for you: without looking at any reference can you answer any C question?, I doubt that very much. Re 'the one document' this will be the same as e.g. the Keil manuals, great if you already know, if you do not, you will never find it. I know a lot about C where I do not know the name of it, e.g. I knew about and understood 'integer promotion' years before I remembered the fancy name.

    (Note that this would be quite a small subset of the document).
    who stated "this is a professional forum, not a playground"? remarks like this makes it obvious that you consider it a playground.

    Erik

  • missed that one
    you sure are. The Cidiots preach using malloc, function pointers, switch etc regardless of the platform and compiler

    So you think that writing correct 'C' makes one a 'Cidiot'?

    I just now realize that the abhove states that you sopport "using malloc, function pointers, switch etc" which, now that you speak of incompetence show how grossly incomptent YOU are in '51 C.

    Erik

  • This is a discussion I should avoid, because of the heat in it but...

    It is a bit dangerous to look at the assembler output and use that as the definition of "bug-free". It may only be used to check for "expected" behaviour. The C standard mentions a number of implementation-specific behaviour, where great care is needed. The next version of a compiler may change it's behaviour, generating "buggy" - or actually unexpected (by the developer) - instruction sequences without being wrong. The original bug (or incorrect assumption) in the source code is woken, and the application stops behaving as expected.

    In some cases it is enough that the compiler manual or other accompnaying documents specifies the design choices made. I some cases the design choices and limitations are available as constants in the include files.

    Alas, some embedded compilers can break the standard quite violently :(

    By the way,

  • It is a bit dangerous to look at the assembler output and use that as the definition of "bug-free".
    No argument with that. However, if you have doubts about a construct, looking at the assembler can often alleviate your doubts.
    Would I recommend that method as a general modus operandi, of course not.
    However, I only run into uncharted waters (what will this do?) about once or twice a year (contradicting Jack, I am, actually, quite proficient in C) and when I have no idea about what keyword to look for in the manuals, it can be quite helpful to look at the assembler generated.

    It may only be used to check for "expected" behaviour. The C standard mentions a number of implementation-specific behaviour, where great care is needed. The next version of a compiler may change it's behaviour, generating "buggy" - or actually unexpected (by the developer) - instruction sequences without being wrong. The original bug (or incorrect assumption) in the source code is woken, and the application stops behaving as expected.
    exactly, and for that reason, looking at the assembler should not be the primary source of information, but on a rare occasion of doubt and no "keyword knowledge" it is way better than nothing.

    Erik

    PS to Jack; if you suggest that in such a case one should read the manual from beginning to end to find the applicable, you must be a raw amateur to have that much time on hand.

  • This is a discussion I should avoid, because of the heat in it

    au contraire it is refereshing to see a counterpoint to my statement that is impersonal, detailled and descriptive.

    Erik

  • absolutely not, just that your opinion of what "correct 'C'" (bug free is not good enought) does.

    If you don't understand the language you won't be able to use it correctly. It's the same situation with any tool. In the case of a programming language the result is likely to be code hiding subtle bugs.

    [My code] IS bug free

    Even an expert programmer would be hard pushed to make that sort of statement with confidence about something less trivial than a few lines of code.

    but I will bet that compared to me you are GROSSLY 'incompetent' in '51 C as shown by you pushing all comments about timing aside.

    Charming. I explained to you why I passed over those particular comments.

    where do you get the "without understanding why" from.

    From the example you posted earlier in this thread. Just to reiterate: You wrote code that did not give the expected result. You changed it until it did. You concluded that the reason the first code didn't 'work' was due to an, er, 'inconsistency' in the compiler's behaviour when in fact it was faulty 'C' code.

    How much clearer can it be?

    Do you really believe that when something does not work and I solve it I learn NOTHING?

    Yes. In the example you posted you learned nothing. You actually came up with misinformation to explain what you were seeing!

    what about your cavalier approach to program design compared to your approach to coding where you concentrate instead of where it matters?

    I don't have a cavalier approach to program design. As for the rest of the sentence, could you rephrase it in such a way a human could parse it?

    I do not 'refuse' why would I, i have a copy.

    That just makes it even stranger:
    1) You have a copy of the 'C' standard.
    2) You don't refuse to read it.

    Ok, I'll rephrase the question:
    'Why don't you read it?'.

    I just do not see why asking in a forum is so terrible and show 'incompetence'.

    It isn't, but you didn't ask in the forum. You posted your problem to highlight what you thought was an 'inconsistency' in the compiler's behaviour.

    Now one question for you: without looking at any reference can you answer any C question?

    Of course not. That's why I read the manual. Will you ever get this?

    I knew about and understood 'integer promotion' years before I remembered the fancy name.

    From the sublime to the ridiculous. The whole point is that you have demonstrated that you *don't* understand integer promotion.

    (Note that this would be quite a small subset of the document).
    who stated "this is a professional forum, not a playground"? remarks like this makes it obvious that you consider it a playground.

    The majority of the document covers the standard library. You've made it pretty clear you use very little (if any) of the standard library hence the parts of the 'C' language you actually use are covered by quite a small subset of the document. I guess you would have realised that if you had taken a look at it.

  • However, I only run into uncharted waters (what will this do?) about once or twice a year (contradicting Jack, I am, actually, quite proficient in C) and when I have no idea about what keyword to look for in the manuals, it can be quite helpful to look at the assembler generated.

    I'm curious. If you don't know what keyword to look up in the manual, how do manage to type it in, compile it and look at the assembler output?

  • I'm curious. If you don't know what keyword to look up in the manual, how do manage to type it in, compile it and look at the assembler output?
    have you sever typed "integer promotion" in a program?

    Erik

  • you just proved my point:
    "you may very7 well be more 'competent' than me in the finer nuances of C but I will bet that compared to me you are GROSSLY 'incompetent' in '51 C"

    The majority of the document covers the standard library.
    Give me a list of thing in "the standard library" that it handled efficiently in '51 C

    Erik

  • you just proved my point:
    "you may very7 well be more 'competent' than me in the finer nuances of C but I will bet that compared to me you are GROSSLY 'incompetent' in '51 C"

    You need to offer some sort of explanation as to how I have proved your point.

    Give me a list of thing in "the standard library" that it handled efficiently in '51 C

    Why?

  • have you sever typed "integer promotion" in a program?

    No, that would be silly. 'integer promotion' is not a keyword.

    What's your point?

  • You said If you don't know what keyword to look up in the manual, how do manage to type it in, compile it and look at the assembler output?

    As an example, if the problem is 'integer promotion' and someone, while being fully aware of the concept has no idea what it is called, how do you suggest they "look it up in the manual". As an example, it is possible to
    Oh, now I get it: stop working for a couple of days and study K&R, their boss will appreciate that.

    Erik

  • Give me a list of thing in "the standard library" that it handled efficiently in '51 C

    Why?

    obvious answer when you cant, because there aren't any.

    Erik

  • you just proved my point:
    "you may very7 well be more 'competent' than me in the finer nuances of C but I will bet that compared to me you are GROSSLY 'incompetent' in '51 C"

    You need to offer some sort of explanation as to how I have proved your point.

    The very mention of the 'importance' of the standard C libraries, when discussing the '51.

    Erik