473,409 Members | 1,983 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,409 software developers and data experts.

regarding "goto" in C

M.B
Guys,
Need some of your opinion on an oft beaten track
We have an option of using "goto" in C language, but most testbooks
(even K&R) advice against use of it.
My personal experience was that goto sometimes makes program some more
cleaner and easy to understand and also quite useful (in error handling
cases).
So why goto is outlawed from civilized c programmers community.

is there any technical inefficiency in that.

Thank you

Jan 4 '06
77 3939
we******@gmail.com wrote:
I personally follow only one rule regarding goto: avoid using it unless
using it leads to either clearer code or faster (executing) code. This
rule alone is sufficient to make the use of goto fairly uncommon in my
code to the point of "spaghetti code" never being an issue. (If
there's one exception it would have to be parsers -- but in those cases
even the cleanest control structures don't actually lead to a clearer
representation of the parser.)


I've never had to use a goto in a parser; could you unpack the reasons
why you've wanted one? [email if it's likely to be wildly off-topic.]

--
Chris "believes seventeen improbable things before coffee" Dollin
Seventeen, forty-two - what else is there?
Jan 9 '06 #51
Chris Dollin wrote:
we******@gmail.com wrote:

I personally follow only one rule regarding goto: avoid using it unless
using it leads to either clearer code or faster (executing) code. This
rule alone is sufficient to make the use of goto fairly uncommon in my
code to the point of "spaghetti code" never being an issue. (If
there's one exception it would have to be parsers -- but in those cases
even the cleanest control structures don't actually lead to a clearer
representation of the parser.)

I've never had to use a goto in a parser; could you unpack the reasons
why you've wanted one? [email if it's likely to be wildly off-topic.]


As a *troll* I use goto often to increase execution speed, easing code
readability mostly in library utilities that I write once and never look at again.

Here is my general structure.

int func(arguments)
{
int error = 0;

/* lengthy function code listing */

/* at various "test" points in function the test below exists */
if (something_aint_right)
{
error = 1;
goto FINAL_func;
}

FINAL_func:
/* clean up any local resources, like malloc() calls, device opens, etc */

if (error)
{
/* any aditional code for error processing here. */
}

return(error);
}
This technique simple allows me to not code multiple in line error condition
tests, and give me the ability to immediately jump out when things go bad.
Jan 9 '06 #52
Chris Dollin wrote:
we******@gmail.com wrote:
I personally follow only one rule regarding goto: avoid using it unless
using it leads to either clearer code or faster (executing) code. This
rule alone is sufficient to make the use of goto fairly uncommon in my
code to the point of "spaghetti code" never being an issue. (If
there's one exception it would have to be parsers -- but in those cases
even the cleanest control structures don't actually lead to a clearer
representation of the parser.)


I've never had to use a goto in a parser; could you unpack the reasons
why you've wanted one? [email if it's likely to be wildly off-topic.]


Well, I measure the performance of the code I write, and I have never
used/figured out yacc or bison or any of those tools. Most parsing
that I implement boil down to what I would call state machines with
counters. The gotos are for state transitions. The typical thing that
I've seen is a switch statement wrapped in a while(), but as I
mentioned switch is *extremely* slow as compared to a goto. Goto costs
the CPU almost nothing (at worst 1-clock of empty decode) as compared
to a break->continue->switch (essentially a goto, then a comparison, a
branch, then an indirect branch) which you pay for in the "well
structured" parsers.

--
Paul Hsieh
http://www.pobox.com/~qed/
http://bstring.sf.net/

Jan 9 '06 #53
we******@gmail.com wrote:
John Bode wrote:
.... snip ...
ISTR some verbiage in H&S that the presence of a goto can
hinder some compiler optimizations.


There may be some weak older generation compilers for which that
is true. However, most modern compilers actually internally
transform all control structures to "if ... goto" anyways.


The exception is machine architectures with special instructions
for a looping construct. This includes the HP3000, which has a
special 'for' construct, and the 808x6, which has a 'rep' (repeat)
construct.

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
More details at: <http://cfaj.freeshell.org/google/>
Jan 9 '06 #54
we******@gmail.com writes:
[snip]
You can always use another control structure -- the question is whether
or not doing so makes the code more complicated or slower.

I personally follow only one rule regarding goto: avoid using it unless
using it leads to either clearer code or faster (executing) code. This
rule alone is sufficient to make the use of goto fairly uncommon in my
code to the point of "spaghetti code" never being an issue. (If
there's one exception it would have to be parsers -- but in those cases
even the cleanest control structures don't actually lead to a clearer
representation of the parser.)

The typical cases where goto is useful: 1) when escaping from more than
one level of loop control, 2) when you have more than one "clean up and
return" code fragment that can be reached from even more scenarios
(typically "clean up and return error" versus "clean up and return
sucess".) 3) Any state machine (switch often doesn't make things
clearer, and can make things horrendously slower.) 4) Starting a
performance critical tight loop from the middle.


In the latter case, I'd probably prefer to use Duff's Device (with a
big fat comment block explaining why I really really needed to do
this).
ISTR some verbiage in H&S that the presence of a goto can hinder some
compiler optimizations.


There may be some weak older generation compilers for which that is
true. However, most modern compilers actually internally transform all
control structures to "if ... goto" anyways.


I actually don't know much about the *current* state of compilers, but
the one I worked on (not a C compiler) actually used higher-level
control structures in its intermediate code. A loop, for example, was
explicitly represented as a loop; this made hoisting more
straightforward. ("Hoisting" refers to taking an expression evaluated
inside a loop and moving its evaluation outside the loop.) Gotos were
allowed, but they would make the optimizer's job more difficult.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Jan 9 '06 #55
In article <sa********************@maineline.net>,
Chuck F. <cb********@maineline.net> wrote:
There may be some weak older generation compilers for which that
is true. However, most modern compilers actually internally
transform all control structures to "if ... goto" anyways.
The exception is machine architectures with special instructions
for a looping construct. This includes the HP3000, which has a
special 'for' construct, and the 808x6, which has a 'rep' (repeat)
construct.


I think you're mixing up two separate parts of the compiler here. In
a typical modern compiler, the control structures will be converted to
linear blocks with jumps between them regardless of the target
architecture. If appropriate, some of those blocks will result in
generation of "rep" instructions in a later phase.

-- Richard
Jan 9 '06 #56
In article <11*********************@f14g2000cwb.googlegroups. com>,
we******@gmail.com wrote:
Chris Dollin wrote:
we******@gmail.com wrote:
I personally follow only one rule regarding goto: avoid using it unless
using it leads to either clearer code or faster (executing) code. This
rule alone is sufficient to make the use of goto fairly uncommon in my
code to the point of "spaghetti code" never being an issue. (If
there's one exception it would have to be parsers -- but in those cases
even the cleanest control structures don't actually lead to a clearer
representation of the parser.)


I've never had to use a goto in a parser; could you unpack the reasons
why you've wanted one? [email if it's likely to be wildly off-topic.]


Well, I measure the performance of the code I write, and I have never
used/figured out yacc or bison or any of those tools. Most parsing
that I implement boil down to what I would call state machines with
counters. The gotos are for state transitions. The typical thing that
I've seen is a switch statement wrapped in a while(), but as I
mentioned switch is *extremely* slow as compared to a goto. Goto costs
the CPU almost nothing (at worst 1-clock of empty decode) as compared
to a break->continue->switch (essentially a goto, then a comparison, a
branch, then an indirect branch) which you pay for in the "well
structured" parsers.


One suggestion for a C extension:

continue <expr>;

which can be used within a switch statement: It evaluates the
expression, then repeats the original switch statement with the value of
<expr> instead of the original value of the switch statement. Obviously
this can be optimised to a simple jump instruction if <expr> is a
constant expression. Would that get rid of your goto's?

(This extension wouldn't break any existing code, since it is impossible
in the current C language to have a 'continue' followed by anything but
a semicolon).
Jan 10 '06 #57
In article <sa********************@maineline.net>,
"Chuck F. " <cb********@yahoo.com> wrote:
we******@gmail.com wrote:
John Bode wrote:

... snip ...
ISTR some verbiage in H&S that the presence of a goto can
hinder some compiler optimizations.


There may be some weak older generation compilers for which that
is true. However, most modern compilers actually internally
transform all control structures to "if ... goto" anyways.


The exception is machine architectures with special instructions
for a looping construct. This includes the HP3000, which has a
special 'for' construct, and the 808x6, which has a 'rep' (repeat)
construct.


I bet good compilers will still _first_ translate everything into "if
.... goto" and _then_ find situations where special machine instructions
can be used. For example, cases where the x86 "rep" prefix can be used
are quite rare.
Jan 10 '06 #58
Christian Bau wrote:
we******@gmail.com wrote:
Chris Dollin wrote:
we******@gmail.com wrote:
> I personally follow only one rule regarding goto: avoid using it unless
> using it leads to either clearer code or faster (executing) code. This
> rule alone is sufficient to make the use of goto fairly uncommon in my
> code to the point of "spaghetti code" never being an issue. (If
> there's one exception it would have to be parsers -- but in those cases
> even the cleanest control structures don't actually lead to a clearer
> representation of the parser.)

I've never had to use a goto in a parser; could you unpack the reasons
why you've wanted one? [email if it's likely to be wildly off-topic.]


Well, I measure the performance of the code I write, and I have never
used/figured out yacc or bison or any of those tools. Most parsing
that I implement boil down to what I would call state machines with
counters. The gotos are for state transitions. The typical thing that
I've seen is a switch statement wrapped in a while(), but as I
mentioned switch is *extremely* slow as compared to a goto. Goto costs
the CPU almost nothing (at worst 1-clock of empty decode) as compared
to a break->continue->switch (essentially a goto, then a comparison, a
branch, then an indirect branch) which you pay for in the "well
structured" parsers.


One suggestion for a C extension:

continue <expr>;

which can be used within a switch statement: It evaluates the
expression, then repeats the original switch statement with the value of
<expr> instead of the original value of the switch statement. Obviously
this can be optimised to a simple jump instruction if <expr> is a
constant expression. Would that get rid of your goto's?


Yes it would -- I think we've discussed this here before, and I
endorsed that or a similar change as well. But I can use goto and an
extra label today ... so, the value of this may not be extremely high.

--
Paul Hsieh
http://www.pobox.com/~qed/
http://bstring.sf.net/

Jan 10 '06 #59
Christian Bau wrote
(in article
<ch*********************************@slb-newsm1.svr.pol.co.uk>):
For example, cases where the x86 "rep" prefix can be used
are quite rare.


Not at all. Anytime you use memcpy() with a large len
parameter, it can be used to very good effect. memcmp() is
another.

However, I can't come up with a good example offhand for using
rep during goto or switch evaluation, but there probably are a
few.
--
Randy Howard (2reply remove FOOBAR)
"The power of accurate observation is called cynicism by those
who have not got it." - George Bernard Shaw
How 'bout them Horns?

Jan 10 '06 #60
On 2006-01-10, we******@gmail.com <we******@gmail.com> wrote:
Christian Bau wrote:
we******@gmail.com wrote:
> Chris Dollin wrote:
> > we******@gmail.com wrote:
> > > I personally follow only one rule regarding goto: avoid using it unless
> > > using it leads to either clearer code or faster (executing) code. This
> > > rule alone is sufficient to make the use of goto fairly uncommon in my
> > > code to the point of "spaghetti code" never being an issue. (If
> > > there's one exception it would have to be parsers -- but in those cases
> > > even the cleanest control structures don't actually lead to a clearer
> > > representation of the parser.)
> >
> > I've never had to use a goto in a parser; could you unpack the reasons
> > why you've wanted one? [email if it's likely to be wildly off-topic.]
>
> Well, I measure the performance of the code I write, and I have never
> used/figured out yacc or bison or any of those tools. Most parsing
> that I implement boil down to what I would call state machines with
> counters. The gotos are for state transitions. The typical thing that
> I've seen is a switch statement wrapped in a while(), but as I
> mentioned switch is *extremely* slow as compared to a goto. Goto costs
> the CPU almost nothing (at worst 1-clock of empty decode) as compared
> to a break->continue->switch (essentially a goto, then a comparison, a
> branch, then an indirect branch) which you pay for in the "well
> structured" parsers.


One suggestion for a C extension:

continue <expr>;

which can be used within a switch statement: It evaluates the
expression, then repeats the original switch statement with the value of
<expr> instead of the original value of the switch statement. Obviously
this can be optimised to a simple jump instruction if <expr> is a
constant expression. Would that get rid of your goto's?


Yes it would -- I think we've discussed this here before, and I
endorsed that or a similar change as well. But I can use goto and an
extra label today ... so, the value of this may not be extremely high.


"goto case" would be possibly a more obvious way to implement the
functionality described.
Jan 10 '06 #61
Randy Howard wrote:
Christian Bau wrote:
For example, cases where the x86 "rep" prefix can be used
are quite rare.
Not at all. Anytime you use memcpy() with a large len
parameter, it can be used to very good effect.


Well, the real question here is: what do you mean by "good effect"? I
think a lot of x86 compilers *DO* use REP MOVSD here, but they are all
slower than the best method which is to operate in larger load and
store blocks. AMD gives some same code on their site somewhere that
demonstrates how this is done -- you can truly saturate the BUS this
way.
[...] memcmp() is another.
I doubt that REP SCASB compares well with Mycroft's trick, but again, I
conceed that a lot of compilers do it this way. You might as well
complete the circle: memset could be implemented as REP STOS*.
However, I can't come up with a good example offhand for using
rep during goto or switch evaluation, but there probably are a
few.


The REP prefix can only be applied to the LODS* STOS* and SCAS*
instructions, which are really just block memory operations. Goto and
switch could only be involved if the compiler massively simplified your
control structures down to the equivalent of memcpy, or memcmp, and
then actively made the choice to emit these instructions in those
cases. Its actually just as likely that a compiler emitted a REP MOVS*
when performing a struct copy.

--
Paul Hsieh
http://www.pobox.com/~qed/
http://bstring.sf.net/

Jan 10 '06 #62
M.B wrote:
Guys,
Need some of your opinion on an oft beaten track
We have an option of using "goto" in C language, but most testbooks
(even K&R) advice against use of it.
My personal experience was that goto sometimes makes program some more
cleaner and easy to understand and also quite useful (in error handling
cases).
So why goto is outlawed from civilized c programmers community.

is there any technical inefficiency in that.

Thank you


I have religiously refused to use goto in a C program (I've been forced
to use it in COBOL), with this one exception. I found it a great way to
handle exception handling where I was setting up the environment for a
complicated program. If something went wrong on the way in it got
messier the further in you went. The goto provided an elegant solution.
However, I advise extreme judicious use of goto. The example is not
complete, but it is standard C if you ignore the 3rd party library
functions.

if ( ( dans_fp = fopen( dansfile_buf, "r+b" ) ) == NULL ) {
msg = "Error: Unable to open Dan's Report File.";
goto exception_1;
}

/************************************************** ****************/
/* Open the extract file reading. */
/************************************************** ****************/

else if ( ( extract_fp = fopen( extract_buf, "r" ) ) == NULL ) {
msg = "Error: Unable to open Ladder Extract file.";
goto exception_2;
}

/************************************************** ****************/
/* Open the ladder file as output. */
/************************************************** ****************/

else if ( ( ladder_fp = fopen( input_buf, "w" ) ) == NULL ) {
msg = "Error: Unable to open Ladder Input file.";
goto exception_3;
}

/************************************************** ****************/
/* Create the index tree. */
/************************************************** ****************/

else if ((tree = cbcreate(index,DEFAULT_COMPARE, 1024)) == NULL) {
msg = "Error: Unable to create ladder index file.";
goto exception_4;
}

/************************************************** ****************/
/* Now, build the ladder index. */
/************************************************** ****************/

if ( build_ladder_index( tree, dans_fp ) == EXIT_FAILURE ) {
msg = "Error: Unable to build ladder index file.";
goto exception_5;
}
else {

/************************************************** ************/
/* Do normal processing here. Code snipped. */
/************************************************** ************/

/************************************************** ************/
/* Close everything down normally. */
/************************************************** ************/

fclose( dans_fp );
fclose( extract_fp );
fclose( ladder_fp );
cbclose( tree );
remove( index );

}
return EXIT_SUCCESS;

/************************************************** ********************/
/* Here I deal with the exceptions. They are structured to undo any */
/* opens and file creations, and to print the proper message. */
/************************************************** ********************/

exception_5:
cbclose( tree );
remove( index );
exception_4:
fclose( ladder_fp );
remove( input_buf );
exception_3:
fclose( extract_fp );
exception_2:
fclose( dans_fp );
exception_1:
beep();
wn_msg( msg );
return EXIT_FAILURE;
Jan 10 '06 #63
Richard Tobin wrote:
Chuck F. <cb********@maineline.net> wrote:
There may be some weak older generation compilers for which
that is true. However, most modern compilers actually
internally transform all control structures to "if ... goto"
anyways.

The exception is machine architectures with special
instructions for a looping construct. This includes the
HP3000, which has a special 'for' construct, and the 808x6,
which has a 'rep' (repeat) construct.


I think you're mixing up two separate parts of the compiler
here. In a typical modern compiler, the control structures will
be converted to linear blocks with jumps between them regardless
of the target architecture. If appropriate, some of those
blocks will result in generation of "rep" instructions in a
later phase.


A compiler is a compiler, and includes whatever phases or passes
are needed to go from source to executable. Code generation and
optimization is part of that.

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
More details at: <http://cfaj.freeshell.org/google/>
Jan 10 '06 #64
Jordan Abel wrote:
On 2006-01-10, we******@gmail.com <we******@gmail.com> wrote:
Christian Bau wrote:
One suggestion for a C extension:

continue <expr>;

which can be used within a switch statement: It evaluates the
expression, then repeats the original switch statement with the value of
<expr> instead of the original value of the switch statement. Obviously
this can be optimised to a simple jump instruction if <expr> is a
constant expression. Would that get rid of your goto's?


Yes it would -- I think we've discussed this here before, and I
endorsed that or a similar change as well. But I can use goto and an
extra label today ... so, the value of this may not be extremely high.


"goto case" would be possibly a more obvious way to implement the
functionality described.


Yes, but that would allow jumping inside from outside of the switch,
which is not likely to promote better structure. (Its more flexible,
but goto is always more flexible -- that's not the point.) Personally,
either one accomplishes the same thing for me, so I would accept
whichever one was added to the language.

--
Paul Hsieh
http://www.pobox.com/~qed/
http://bstring.sf.net/

Jan 10 '06 #65
In article <11**********************@g49g2000cwa.googlegroups .com>,
<we******@gmail.com> wrote:
"goto case" would be possibly a more obvious way to implement the
functionality described.
Yes, but that would allow jumping inside from outside of the switch,


Since you can have multiple switch statements with the same cases,
you would probably want to prohibit that anyway.

-- Richard
Jan 10 '06 #66
In article <x_******************************@maineline.net> ,
Chuck F. <cb********@maineline.net> wrote:
There may be some weak older generation compilers for which
that is true. However, most modern compilers actually
internally transform all control structures to "if ... goto"
anyways. The exception is machine architectures with special
instructions for a looping construct. This includes the
HP3000, which has a special 'for' construct, and the 808x6,
which has a 'rep' (repeat) construct.
I think you're mixing up two separate parts of the compiler
here. In a typical modern compiler, the control structures will
be converted to linear blocks with jumps between them regardless
of the target architecture. If appropriate, some of those
blocks will result in generation of "rep" instructions in a
later phase.
A compiler is a compiler, and includes whatever phases or passes
are needed to go from source to executable. Code generation and
optimization is part of that.


That's true, but irrelevant. You said that machines like the HP3000
were an exception to compilers transforming control structures to
gotos. They aren't. They do such a transformation, but transform it
back again.

-- Richard
Jan 10 '06 #67
we******@gmail.com wrote
(in article
<11*********************@g47g2000cwa.googlegroups. com>):
Randy Howard wrote:
Christian Bau wrote:
For example, cases where the x86 "rep" prefix can be used
are quite rare.


Not at all. Anytime you use memcpy() with a large len
parameter, it can be used to very good effect.


Well, the real question here is: what do you mean by "good effect"? I
think a lot of x86 compilers *DO* use REP MOVSD here, but they are all
slower than the best method which is to operate in larger load and
store blocks. AMD gives some same code on their site somewhere that
demonstrates how this is done -- you can truly saturate the BUS this
way.


That's quite true, and I've done it. A few years ago I was
asked to write a multi-threaded tool to do that very thing to
memory back when hyperthreading first started showing up in SMP
server hardware, and I well remember employing quite a few
different methods, including the one AMD recommended. However,
the discussion here was uses for rep.

BTW, even the simple speedup mentioned above wasn't used by
Microsoft's compiler at the time, yet gcc did.
[...] memcmp() is another.


I doubt that REP SCASB compares well with Mycroft's trick, but again, I
conceed that a lot of compilers do it this way. You might as well
complete the circle: memset could be implemented as REP STOS*.


If you want to list all possible uses of it, knock yourself out.
Around late 2000, Microsoft's memcmp() implementation was
horribly bad and I easily beat it by 40% with a homegrown
implementation and about 20 minutes worth of work with inline
asm. I'd certainly hope they've improved since then, but I
haven't played that game in quite a while.
--
Randy Howard (2reply remove FOOBAR)
"The power of accurate observation is called cynicism by those
who have not got it." - George Bernard Shaw
How 'bout them Horns?

Jan 10 '06 #68
Randy Howard <ra*********@FOOverizonBAR.net> writes:
Christian Bau wrote:
For example, cases where the x86 "rep" prefix can be used are
quite rare.

Not at all. Anytime you use memcpy() with a large len parameter, it
can be used to very good effect. memcmp() is another.


Not really. You get better performance from unrolling the loop a
little, and using FPU / MMX / SSE registers when available.

DES
--
Dag-Erling Smørgrav - de*@des.no
Jan 10 '06 #69
Dag-Erling Smørgrav wrote
(in article <86************@xps.des.no>):
Randy Howard <ra*********@FOOverizonBAR.net> writes:
Christian Bau wrote:
For example, cases where the x86 "rep" prefix can be used are
quite rare.

Not at all. Anytime you use memcpy() with a large len parameter, it
can be used to very good effect. memcmp() is another.


Not really. You get better performance from unrolling the loop a
little, and using FPU / MMX / SSE registers when available.


I wasn't referring to a drag race. You can all put your
professional pre-optimization hats away.

--
Randy Howard (2reply remove FOOBAR)
"The power of accurate observation is called cynicism by those
who have not got it." - George Bernard Shaw
How 'bout them Horns?

Jan 10 '06 #70
On 2006-01-10, we******@gmail.com <we******@gmail.com> wrote:
Jordan Abel wrote:

"goto case" would be possibly a more obvious way to implement the
functionality described.


Yes, but that would allow jumping inside from outside of the switch,


Or you could say it doesn't - it's your extension.
Jan 10 '06 #71
In article <00*****************************@news.verizon.net> ,
Randy Howard <ra*********@FOOverizonBAR.net> wrote:
Christian Bau wrote
(in article
<ch*********************************@slb-newsm1.svr.pol.co.uk>):
For example, cases where the x86 "rep" prefix can be used
are quite rare.
Not at all. Anytime you use memcpy() with a large len
parameter, it can be used to very good effect. memcmp() is
another.


No go back to the original context, and find me a _loop_ that can make
use of the "rep" prefix.
However, I can't come up with a good example offhand for using
rep during goto or switch evaluation, but there probably are a
few.

Jan 10 '06 #72
In article <11**********************@g49g2000cwa.googlegroups .com>,
we******@gmail.com wrote:
Jordan Abel wrote:
On 2006-01-10, we******@gmail.com <we******@gmail.com> wrote:
Christian Bau wrote:
> One suggestion for a C extension:
>
> continue <expr>;
>
> which can be used within a switch statement: It evaluates the
> expression, then repeats the original switch statement with the value of
> <expr> instead of the original value of the switch statement. Obviously
> this can be optimised to a simple jump instruction if <expr> is a
> constant expression. Would that get rid of your goto's?

Yes it would -- I think we've discussed this here before, and I
endorsed that or a similar change as well. But I can use goto and an
extra label today ... so, the value of this may not be extremely high.


"goto case" would be possibly a more obvious way to implement the
functionality described.


Yes, but that would allow jumping inside from outside of the switch,
which is not likely to promote better structure. (Its more flexible,
but goto is always more flexible -- that's not the point.) Personally,
either one accomplishes the same thing for me, so I would accept
whichever one was added to the language.


One reason that I forgot that was somewhere hidden in my mind for
chosing "continue": "continue" inside a switch statement is extremely
ugly. Within a loop (for, do, or while loop) "continue" and "break" both
refer to the loop being executed. Within a "switch" statement, "break"
refers to the "switch" statement, but "continue" refers to any loop that
happens to include the switch statement. I would prefer if an ordinary
"continue" statement within a switch statement were illegal, because
someone who tries to "continue" a loop from within a switch statement
might be very tempted to "break" a loop from within the same switch
statement, and that won't work.
Jan 10 '06 #73
Richard Tobin wrote:
<we******@gmail.com> wrote:
"goto case" would be possibly a more obvious way to
implement the functionality described.

Yes, but that would allow jumping inside from outside of the
switch,


Since you can have multiple switch statements with the same
cases, you would probably want to prohibit that anyway.


This is getting OT for c.l.c. comp.std.c would be suitable.

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
More details at: <http://cfaj.freeshell.org/google/>
Jan 11 '06 #74
Richard Tobin wrote:
Chuck F. <cb********@maineline.net> wrote:
> There may be some weak older generation compilers for
> which that is true. However, most modern compilers
> actually internally transform all control structures to
> "if ... goto" anyways. The exception is machine architectures with special
instructions for a looping construct. This includes the
HP3000, which has a special 'for' construct, and the
808x6, which has a 'rep' (repeat) construct. I think you're mixing up two separate parts of the compiler
here. In a typical modern compiler, the control structures
will be converted to linear blocks with jumps between them
regardless of the target architecture. If appropriate, some
of those blocks will result in generation of "rep"
instructions in a later phase.

A compiler is a compiler, and includes whatever phases or
passes are needed to go from source to executable. Code
generation and optimization is part of that.


That's true, but irrelevant. You said that machines like the
HP3000 were an exception to compilers transforming control
structures to gotos. They aren't. They do such a
transformation, but transform it back again.


No, I said that some machine had looping instructions which a
compiler could use in the code generation phase. They don't have
to. At least that is what I meant.

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
More details at: <http://cfaj.freeshell.org/google/>
Jan 11 '06 #75
Christian Bau wrote:
.... snip ...
No go back to the original context, and find me a _loop_ that
can make use of the "rep" prefix.


size_t slgh(const char *s)
{
const char *start = s;

while (*s++) continue;
return s - start;
}

can probably use repnz to advantage.

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
More details at: <http://cfaj.freeshell.org/google/>
Jan 11 '06 #76
Christian Bau wrote:
In article <11**********************@g49g2000cwa.googlegroups .com>,
we******@gmail.com wrote:

Jordan Abel wrote:
On 2006-01-10, we******@gmail.com <we******@gmail.com> wrote:

Christian Bau wrote:

>One suggestion for a C extension:
>
> continue <expr>;
>
>which can be used within a switch statement: It evaluates the
>expression, then repeats the original switch statement with the value of
><expr> instead of the original value of the switch statement. Obviously
>this can be optimised to a simple jump instruction if <expr> is a
>constant expression. Would that get rid of your goto's?

Yes it would -- I think we've discussed this here before, and I
endorsed that or a similar change as well. But I can use goto and an
extra label today ... so, the value of this may not be extremely high.

"goto case" would be possibly a more obvious way to implement the
functionality described.


Yes, but that would allow jumping inside from outside of the switch,
which is not likely to promote better structure. (Its more flexible,
but goto is always more flexible -- that's not the point.) Personally,
either one accomplishes the same thing for me, so I would accept
whichever one was added to the language.

One reason that I forgot that was somewhere hidden in my mind for
chosing "continue": "continue" inside a switch statement is extremely
ugly. Within a loop (for, do, or while loop) "continue" and "break" both
refer to the loop being executed. Within a "switch" statement, "break"
refers to the "switch" statement, but "continue" refers to any loop that
happens to include the switch statement. I would prefer if an ordinary
"continue" statement within a switch statement were illegal, because
someone who tries to "continue" a loop from within a switch statement
might be very tempted to "break" a loop from within the same switch
statement, and that won't work.


What, forbid something because it's counterintuitive? That's decidedly
non-C. Think of the programmers who've made good use of this! Well, some use
of this. For some reason.

S.
Jan 11 '06 #77
I received an email question on my earlier posting. It is being
answered here. Read here, post here.

Thad Smith wrote:
In general, there is some inefficiency with the elimination of goto. In
order to eliminate goto, you often have to implement additional
variables or flags to carry information from an inner loop to the
outside in order to stop intermediate processing, which is not needed if
you simply jump directly out of a loop. Also, there tends to be some
code duplication. Some people, such as I, cheat by returning from a
function more than one place in the body, a violation of the strict
structured approach.
The responder wrote (via email):
I am a novice in C. You mentioned in your message that
you can break out of a function from more than one place,
and it is violation of structured programming. Can you elaborate
on how you do that and why that runs counter to good structure?


To break out of a function I execute a return statement. In general,
there may be several error cases in a function that can be handled by
simply returning an error value, so once the error determination is
made, I return an error value. The following code is then at the same
nesting level of the preceding code. Of course, I have to make sure
that I have taken care of any required cleanup before exiting. If you
want to find all the places where function returns, look for "return".

Regarding why it is not purely structured, without gotos code can be
constructed of blocks. Blocks may be combined by selection, iteration,
and sequence to form larger blocks. There are ways to reason about
program correctness using preconditions and postconditions on a block of
code, and rules to manipulate the conditions as you combine or decompose
code via the classic methods. Inserting gotos makes formal analysis
harder, at least in the general case.

A subroutine or function can be considered a code block. If you exit
from multiple points, as described above, it is equivalent to executing
a goto function_end.

Controlled use of program controls (goto, break, continue, return) can
yield code that can be easily understood and analyzed, if desired. IMO,
if a program with the additional controls could be easily converted
into an equivalent program using only the classic combining forms, its
in good form.

--
Thad
Jan 13 '06 #78

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

20
by: DraguVaso | last post by:
Hi, As a former VB-programmer I'm used to the "on error goto"-errorhandling. I see that in actually all the VB.NET-samples I can fin people use the "Try - catch"-errorhandling. Which of the...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.