> 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.
Reply by Hans-Bernhard Bröker●April 27, 20082008-04-27
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.
Reply by CBFalconer●April 27, 20082008-04-27
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 **
Reply by Alex Colvin●April 27, 20082008-04-27
>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�f
Reply by Nils●April 27, 20082008-04-27
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
Reply by Andrew Smallshaw●April 27, 20082008-04-27
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
Reply by ●April 27, 20082008-04-27
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.
Reply by Steve at fivetrees●April 27, 20082008-04-27
"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
Reply by Steve at fivetrees●April 27, 20082008-04-27
"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
Reply by Steve at fivetrees●April 27, 20082008-04-27
"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)
Signal Processing Engineer Seeking a DSP Engineer to tackle complex technical challenges. Requires expertise in DSP algorithms, EW, anti-jam, and datalink vulnerability. Qualifications: Bachelor's degree, Secret Clearance, and proficiency in waveform modulation, LPD waveforms, signal detection, MATLAB, algorithm development, RF, data links, and EW systems. The position is on-site in Huntsville, AL and can support candidates at 3+ or 10+ years of experience.