EmbeddedRelated.com
Forums

C and MISRA, blues... (arithmetic shifts)

Started by Nils April 24, 2008
CBFalconer wrote:
> David Brown wrote: >> CBFalconer wrote: >>> Steve at fivetrees wrote: >>> > ... snip ... >>>> Summary: avoiding goto as a design concept is a Good Thing. >>>> Avoiding gotos as a means of implementing good structure is >>>> simply misunderstanding the point. I've seen (possibly on this >>>> ng) someone defending goto on the basis that CPUs only know >>>> about branches and jumps anyway. Follocks. >>> Not according to me. Consider the following function outline: >>> >>> int foo( /* whatever */ ) { >>> int errmk = 0; >>> FILE *f1, *f2, *fw; >>> >>> if (!(f1 = fopen(f1name, "r")) { >>> errmk = 1; goto f1bad; >>> } >>> else if (!(f2 = fopen(f2name, "r")) { >>> errmk = 2; goto f2bad; >>> } >>> else if (!(fw = fopen(fwname, "w")) { >>> errmk = 3; goto fwbad; >>> } >>> else { >>> /* files open, play appropriate games */ >>> } >>> fputs(fwendln, fw); >>> fclose(fw); >>> fwbad: >>> fclose(f2); >>> f2bad: >>> fclose(f1); >>> f1bad: >>> return errmk; >>> } >>> >>> There are lots of undetected errors left, that is an outline. >>> Yes, there are other ways to handle it. >> int foo( /* whatever */ ) { >> int errmk = 0; >> FILE *f1, *f2, *fw; >> >> if (!(f1 = fopen(f1name, "r")) errmk = 1; >> else { >> if (!(f2 = fopen(f2name, "r")) errmk = 2; >> else { >> if (!(fw = fopen(fwname, "w")) errmk = 3; >> else { /* Files open */ >> fputs(fwendln, fw); >> fclose(fw); >> }; >> fclose(f2); >> }; >> fclose(f1); >> }; >> return errmk; >> } > > (I have taken liberties reformatting your quote above.) >
Liberties indeed - it is rare that I would write a statement of the form "if (x) y;" without brackets, and I consider it downright foolish to omit the brackets when using "else". The scope for getting your else's out of synchronisation with your if's is just far too great.
> Well, I did say mine was an outline. In practice I would probably > write that the way you did. I guess I wasn't too clear, but I was > trying to illustrate a clear way of using goto with forward jumps. > > I'm lazy and don't use it, but I consider goto clearer than break. >
A forward goto is often a choice for breaking out of nested loops, where a break won't work. Personally, I'd prefer to split the code into a separate function (if you have a situation like this, your function is probably too long anyway) and use a return from within the loop, but that's a matter of choice.
Andrew Reilly wrote:
> On Fri, 25 Apr 2008 18:15:15 -0400, CBFalconer wrote:
>> Yes, you are, but no, he's not. Shifts on negative values are undefined >> behaviour on any system.
> Only in C.
Which just so happens to be the subject matter.
David Brown wrote:
> CBFalconer wrote: >> David Brown wrote: >>
... snip ...
>> >>> int foo( /* whatever */ ) { >>> int errmk = 0; >>> FILE *f1, *f2, *fw; >>> >>> if (!(f1 = fopen(f1name, "r")) errmk = 1; >>> else { >>> if (!(f2 = fopen(f2name, "r")) errmk = 2; >>> else { >>> if (!(fw = fopen(fwname, "w")) errmk = 3; >>> else { /* Files open */ >>> fputs(fwendln, fw); >>> fclose(fw); >>> }; >>> fclose(f2); >>> }; >>> fclose(f1); >>> }; >>> return errmk; >>> } >> >> (I have taken liberties reformatting your quote above.) > > Liberties indeed - it is rare that I would write a statement of > the form "if (x) y;" without brackets, and I consider it > downright foolish to omit the brackets when using "else". The > scope for getting your else's out of synchronisation with your > if's is just far too great.
I can smell the exclamation marks after 'indeed'. :-) However, look at it again. Notice that the elses are tightly associated with the appropriate ifs. At any point following indentation up exposes the controlling statement. I maintain it is hard to misread the flow. It is also vertically compact, which I consider an advantage (and was the primary reason for the reformat). -- [mail]: Chuck F (cbfalconer at maineline dot net) [page]: <http://cbfalconer.home.att.net> Try the download section. ** Posted from http://www.teranews.com **
>I've never seen one that doesn't do an arithmetic right shift >on signed value...
I have. Old MPW C did a 16-bit signed shift as unsigned, using some special 68K operation. I forget the details. That's when I discovered they were undefined. Isn't integer division of negative dividends allowed to truncate to zero or to truncate less. (-1/2 == 0 or ==-1). -- mac the na&#4294967295;f
Alex Colvin schrieb:
> Isn't integer division of negative dividends allowed to truncate to zero > or to truncate less. (-1/2 == 0 or ==-1).
There was an issue with this as well. I remember having worked on a MetroWerks compiler in my game-development days that made signed divisions different to any other compiler. Those guys also messed up switches with negative cases and other stuff as well though. It seems to me like they had big problems with signed/unsigned in general. Don't know how MetroWerks is today. Back 8 years it was a horrible piece of junk. Nils
On 2008-04-25, CBFalconer <cbfalconer@yahoo.com> wrote:
> > Yes, you are, but no, he's not. Shifts on negative values are > undefined behaviour on any system.
Don't confuse "undefined by the standard" with "undefined, period". One of the differences between good tools and merely useful tools is the quality of the documentation. Amongst other things, this includes defining undefined behaviour. It's worth going through to make yourself aware of any areas where the compiler works in a way you don't expect, so you can watch out for those particular cases when undefined behaviour slips in by mistake. Of course, merely reading through that portion increases awareness of undefined aspects in the first place which can only be a good thing. I have hazy memories of the release notes for an old SCO compiler including a note to the effect of "The previous version did this in the undefined case where ..., the new version does something else instead", but can't be bothered digging out the manuals to find an exact reference now. -- Andrew Smallshaw andrews@sdf.lonestar.org
Alex Colvin wrote:

> Isn't integer division of negative dividends allowed to truncate to zero > or to truncate less. (-1/2 == 0 or ==-1).
It was in C90 and successors. As of C99, it's required to truncate towards zero. I have serious doubts that was a good idea.
"CBFalconer" <cbfalconer@yahoo.com> wrote in message 
news:4812862C.82C0DEFE@yahoo.com...
> Steve at fivetrees wrote: >> >> Things like jump tables are not lists of gotos - they're a list >> of (derefenced, if you insist) function pointers. >> >> Summary: avoiding goto as a design concept is a Good Thing. >> Avoiding gotos as a means of implementing good structure is >> simply misunderstanding the point. I've seen (possibly on this >> ng) someone defending goto on the basis that CPUs only know >> about branches and jumps anyway. Follocks. > > Not according to me. Consider the following function outline: > > int foo( /* whatever */ ) { > int errmk = 0; > FILE *f1, *f2, *fw; > > if (!(f1 = fopen(f1name, "r")) { > errmk = 1; goto f1bad; > } > else if (!(f2 = fopen(f2name, "r")) { > errmk = 2; goto f2bad; > } > else if (!(fw = fopen(fwname, "w")) { > errmk = 3; goto fwbad; > } > else { > /* files open, play appropriate games */ > } > fputs(fwendln, fw); > fclose(fw); > fwbad: > fclose(f2); > f2bad: > fclose(f1); > f1bad: > return errmk; > } > > There are lots of undetected errors left, that is an outline. Yes, > there are other ways to handle it.
Ooh. That's truly horrible - but the underlying logic isn't, it's just coded horribly. I'd probably write that as: int foo( /* whatever */ ) { int errmk = 0; FILE *f1, *f2, *fw; BOOL f1_open = FALSE, f2_open = FALSE, fw_open = FALSE; if ( errmk == 0 ) { if ( !( f1 = fopen( f1name, "r" )) errmk = 1; else f1_open = TRUE; } if ( errmk == 0 ) { if ( !( f2 = fopen( f2name, "r" )) errmk = 2; else f2_open = TRUE; } if ( errmk == 0 ) { if ( !(fw = fopen( fwname, "w" )) errmk = 3; else fw_open = TRUE; } if ( errmk == 0 ) { /* files open, play appropriate games */ fputs( fwendln, fw ); } if ( fw_open ) fclose( fw ); if ( f2_open ) fclose( f2 ); if ( f1_open ) fclose( f1 ); return( errmk ); } Note that I've defended myself from code changes - I can move things around, and the initial tests and the final closures are independent of any such changes. Note also that I just can't be doing with this opening-brace-on-end-of-line heresy: braces should visually line up, and that's the end of it ;). YMMV ;). Steve
"Richard Phillips" <raphillips@ntlworld.com> wrote in message 
news:gIDQj.112578$5i5.4642@newsfe6-gui.ntli.net...
> Steve at fivetrees wrote: >> >> Avoiding "goto" means avoiding unstructured design (i.e. using only >> only closed structures - one start, one end, any other context >> signalled by other means than programme flow). > > Sorry, I think that's just wrong. If K+R think it's ok and include it in > the language, I think there must be some point to it. > The one case I've encountered where it's "needed" is deeply nested > conditional code. Often encoutered in communications, where you need to > test lots of conditions before a packet of data is "accepted". If the > data is rejected at the final check, goto gets you right back out > gracefully without lots of extra checking code.
There are plenty of ways of doing exactly this without using gotos (e.g. state machines). I've not used a goto in nearly 30 years, and I pride myself on clean, readable code. I do a lot of comms, so I know whereof you speak - but I think you're missing a load of tricks (e.g. separate validation from use - decompose). Again: it's about the logic, not necessarily the implementation. Steve
"Chris H" <chris@phaedsys.org> wrote in message 
news:IuwkdBEGJtEIFA4t@phaedsys.demon.co.uk...
> In message <SuCdnb4TBovD9I_VnZ2dnUVZ8uadnZ2d@pipex.net>, Steve at > fivetrees <steve@NOSPAMTAfivetrees.com> writes >>"Richard Phillips" <raphillips@ntlworld.com> wrote in message >>news:kukQj.59491$h65.48326@newsfe2-gui.ntli.net... >>> * You're not supposed to use "goto". Avoiding this when you're >>> learning to write code is good practise, but it's very useful in a >>> limited set of circumstances, if used properly. I remember a manager >>> of mine telling a work colleague once that using "goto" was bad >>> practise, I then showed my colleague my copy of K+R which basically >>> put him right. >>> >>> * You're not supposed to exit from a controlled loop prematurely. >> >>Avoiding "goto" means avoiding unstructured design (i.e. using only only >>closed structures - one start, one end, any other context signalled by >>other means than programme flow). > > However as with all things there are a few exceptions where got is the > cleanest solution. In those cases you need to deviate and be able to > stand up in court in 3 years time with your deviation.
Sorry, but I disagree. There are always - ALWAYS - logically-equivalent structured alternatives to goto, which will not bite your ass anywhere near as badly.
> Intestinally the "goto" is bad" came from a paper by Dykstra (not Wilco > :-) and AFAIK no one has really challenged it but just taken it as read. I > know some people are doing some work into it to see if it really is that > bad.
Ignoring the "intestinally": you're kidding! I've said this elsewhere, but the acid test is: if you can't look at a section of code and know how you got there, WARNING. Therein is the danger of goto. You say that people are seriously questioning this? FFS... are they questioning synchronous logic design too?
> I suspect the trouble will be that 90% of those who want to use goto are > the sort of people who will write appalling code anyway and 90% of those > who think goto should be banned would only ever use it very sensibly.
Agreed.
> So it is a self fore filling prophesy:
Ah - you mean a self-fulfilling prophecy. No. 2 or 3 years back I had to review the code of a certain engineer who was not subject to normal peer review on the basis of his, errr, "adherence to open-source methods". Turned out this was a smokescreen. His main() was over 2000 lines long, and was peppered with gotos. Summary - he was a crap coder. I see this a lot - crap coders are crap coders, period. There are good reasons for objecting to goto - Dijkstra was no fool. Those who use goto simply don't understand the subject very well. Steve (ducking and running)