We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
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); }
I just pointed out the (if you insist - percieved) inconsistency.
There is no inconsistency. If you had understood the code you had written you would not have been surprised by the result.
I did not send a 'bug report'
Let's think about this: You had two pieces of code that you thought should give the same result. That means that either you were wrong or the compiler was wrong. I don't imagine you emailed Keil to tell them you were wrong, did you?
Is that so terrible
Yes. Read the manual instead of wasting peoples time.
You seem to have a very negative attitude to those who read the manual. This is strange considering the frequency with which you encourage others to do so. absolutely NOT! I just have " very negative attitude" about your hammering that "your" manual is mandatory. My 'manual' has sufficed me for 15 years. You may, very well know more about the intricacies of special cases in C, I have no probloem with that, I do not need them.
I have had Kochans book since day one and that is my manual. Well, either the book is inadequate or you haven't read it. Let's see: I wonder if I can guess which one is the case? The book in not "inadequate", and I have read it (and still refer to it on occasion); that it might not cover every nook and cranny of the finer, more obscure, details of the language (which, if you use them, will result in code that only the few chosen can understand) is not a problem for me.
I am more interested in studying the finer details of what to code than the finer details of how to code. I have seen lots of s**t from 'professional fully implemeted understanding of C' and none from 'professional fully implemeted understanding of the processor'
Erik
Read the manual instead of wasting peoples time.
1) did I ask YOU to waste time posting here.
2) if you took the time to read the thread (instead of wasting it as you state you do by responding here) you would see that I did not start this thread, just posted that what I had seen might be an answer to the OPs problem.
3) you are welcome to 'hate' me, my skin is thick.
Ps could your attitude against me be that you are offended that I often post "this is not a processor to just willy nilly code C for. You actually need to know the hardware and THINK, not just code 'good C'". I know you will not agree but '51 C is not "just C"
absolutely NOT! I just have " very negative attitude" about your hammering that "your" manual is mandatory.
The 'C' standard defines the language and is therefore the best reference. I would suggest that if you dispute this you are plain wrong.
that it might not cover every nook and cranny of the finer, more obscure, details of the language (which, if you use them, will result in code that only the few chosen can understand) is not a problem for me.
The problem you encountered was with arithmetic using simple integer data types. If your book doesn't cover that it is seriously flawed. I suspect it probably does and the real problem is that you haven't read the appropriate section.
I am more interested in studying the finer details of what to code than the finer details of how to code.
A programming language is a tool. If you aren't prepared to learn how the tool works you won't be able to use it properly. In the context of a programming language this will result in buggy, inefficient code.
did I ask YOU to waste time posting here.
No. I was thinking of the support people who have to read the same old questions over and over again from those who haven't read the manual.
if you took the time to read the thread (instead of wasting it as you state you do by responding here) you would see that I did not start this thread, just posted that what I had seen might be an answer to the OPs problem
I did read the thread and I did notice that you didn't start it. I also noticed that you had again posted code showing a fundamental lack of understanding of the 'C' language and thought that I'd take the opportunity to offer you more encouragement to read the manual and improve your programming skills.
you are welcome to 'hate' me, my skin is thick
Please don't confuse a little constructive criticism with hatred. This is a professional forum not a playground.
You actually need to know the hardware and THINK, not just code 'good C'".
Of course. But you do need to be able to code good 'C'.
I know you will not agree but '51 C is not "just C"
'C' is 'C'. Just because you are using it on an 8051 is no excuse to write poor 'C'.
Read the manual!
I have seem that from ever so many that are totally fluent in C never from someone that is "fluent in the '51".
just an example A Cidiot will have switches all over the place when an if, else if construct is much more efficient in Keil C. yes, I have studied the tool.
Of course. But you do need to be able to code good 'C'. please define "good C", my definition is "bug free" and efficient, not "elegant".
'C' is 'C'. Just because you are using it on an 8051 is no excuse to write poor 'C'. see above.
Please don't confuse a little constructive criticism with hatred. This is a professional forum not a playground. First please note the quotes, I used a word that did not fit exactly. Constructive criticism my a.., I posted a question, what about just answerinmg it straight.
Again, I succesfully code functional time efficient bug free systems, what is the problem?. That I do not 'like' 'char' is that a problem?.That I wonder why a typecast that I did insert is only needed in one case, is that a problem?. That I have found that some 'elegant' C constructs are inefficient when running on '51 hardware and thus advise against them is that a problem?. Should I preact the gospel of "real C" and ignore the platform I work on?. I once laid off a person who reacted to "change that, it takes too long to process" with "then it will not be rea;l C". My 'gospel' is fast code, since my area requires that.
please define "good C", my definition is "bug free" and efficient, not "elegant".
You can't write bug free or efficient code if you don't understand the rules of the programming language you're using.
Returning to the example you posted:
You had a simple piece of code that didn't give the results you expected. So, rather than find out why it behaved as it did you modified it until it did give the result you expected. By the end of this process you had no idea *why* one piece of code appeared to work and the other didn't.
The problem with this 'hack it and see' approach is that you cannot be sure that the code that does appear to give the correct result is actually correct, as you continue to believe the code that gives the wrong result should also be correct. Finally your misplaced self confidence leads you to assume that you've encountered an 'inconsistency' in the way the compiler generates code and that you have stumbled on a workaround.
This might be an acceptable approach for a hobbyist but it certainly isn't for a professional.
Again, I succesfully code functional time efficient bug free systems, what is the problem?
The problem is that they most probably aren't bug free.
That I wonder why a typecast that I did insert is only needed in one case, is that a problem?
Yes, it is. If you don't understand why you needed to use the cast then you are quite possibly just masking a problem. There are very few situations in 'C' where it is necessary to use a cast.
Should I preact the gospel of "real C" and ignore the platform I work on?
Why do you think that writing correct 'C' code somehow precludes understanding the target platform? You seem to think that if you learn how to write correct 'C' then somehow you won't be able to target the 8051? Or am I missing the point?
My 'gospel' is fast code, since my area requires that.
Maybe, but all areas require correct code.
you sure are. The Cidiots preach using malloc, function pointers, switch etc regardless of the platform and compiler
My 'gospel' is fast code, since my area requires that. Maybe, but all areas require correct code. Agreed, but what makes you think my bug free code is not correct? is that because use C instead of preaching it? or is that because I will use many lines for clarity rather than to cram as much as possible into one line to achieve the same in an incomprehensible way? or is that because I think execution time instead of elegance? or is that beacuse I actually occasionally check the assembler output to see if the compiler is time efficient in compiling a given construct however 'right' it may be to a Cidiot? or is it because I do not suppress warnings, but fix them? My original post in this thread was triggered by a warning that DID show the line with the problem, which I then fixed.
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
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.
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.
missed that one you sure are. The Cidiots preach using malloc, function pointers, switch etc regardless of the platform and compiler
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.
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.
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.