By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,159 Members | 980 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,159 IT Pros & Developers. It's quick & easy.

goto

P: n/a
Hi,
I know I know its notoriously bad! I don't want to use it. I was wondering,
does it still exist? If it does, I really don't understand how!? like what
happens if you just goto halfway through a function (no objects properly
constructed!) , or a constructor itself??
Just intrigued!!

Mike
Jul 23 '05 #1
Share this Question
Share on Google+
36 Replies


P: n/a
* Michael:

I know I know its notoriously bad! I don't want to use it. I was wondering,
does it still exist?
Yes.

If it does, I really don't understand how!?
Like always.

like what
happens if you just goto halfway through a function (no objects properly
constructed!) ,
That is forbidden by §6.6.4/3; it won't or shouldn't compile.

or a constructor itself??
?

Just intrigued!!


As you learn more you'll find many more unsafe constructs, in all languages.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Jul 23 '05 #2

P: n/a
Michael wrote:
I know I know its notoriously bad!
Long functions are bad. Short ones have no reason to use 'goto', and thus
'goto' is relatively harmless.
I don't want to use it. I was wondering,
does it still exist? If it does, I really don't understand how!? like what
happens if you just goto halfway through a function (no objects properly
constructed!) , or a constructor itself??


Ordinarily, one should not learn C++ laws via "but my compiler likes it".

In this case, a little VC++ experiment is useful:

goto bar;
string foo;
bar:;

error C2362: initialization of 'foo' is skipped by 'goto bar'

The language designers took care of it. With no legacy C constructors to
support, they ordained compilers reject (relatively) non-structured 'goto'
abuses.

--
Phlip
http://industrialxp.org/community/bi...UserInterfaces
Jul 23 '05 #3

P: n/a

"Alf P. Steinbach" <al***@start.no> wrote in message
news:42****************@news.individual.net...
* Michael:

I know I know its notoriously bad! I don't want to use it. I was wondering, does it still exist?
Yes.

If it does, I really don't understand how!?


Like always.

like what
happens if you just goto halfway through a function (no objects properly
constructed!) ,


That is forbidden by §6.6.4/3; it won't or shouldn't compile.

so what are the limits on what you can 'goto' 'to' ?
local scope?

or a constructor itself??
?

Just intrigued!!


As you learn more you'll find many more unsafe constructs, in all

languages.
--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?

Jul 23 '05 #4

P: n/a
* Michael:

* Alf P. Steinbach:
* Michael:

I know I know its notoriously bad! I don't want to use it. I was
wondering, does it still exist?


Yes.

If it does, I really don't understand how!?


Like always.

like what
happens if you just goto halfway through a function (no objects properly
constructed!) ,


That is forbidden by §6.6.4/3; it won't or shouldn't compile.

so what are the limits on what you can 'goto' 'to' ?
local scope?


Quoting the standard: "It is possible to transfer into a block, but not in a
way that bypasses declarations with initialization."

Btw., don't quote things you don't reply to or irrelevant to your reply;
snipped further quoting.

Download and install <url: http://home.in.tum.de/~jain/software/oe-quotefix/>.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Jul 23 '05 #5

P: n/a
"Michael" <sl***********@hotmail.com> wrote in
news:d1**********@sparta.btinternet.com:
Hi,
I know I know its notoriously bad! I don't want to use it. I was
wondering, does it still exist? If it does, I really don't understand
how!? like what happens if you just goto halfway through a function
(no objects properly constructed!) , or a constructor itself??
Just intrigued!!


Yes goto still exists.

The type of goto you describe is ill-formed. See section 6.7(3) of the
Holy Standard :)
Jul 23 '05 #6

P: n/a
Michael wrote:
Hi,
I know I know its notoriously bad! I don't want to use it. I was wondering,
does it still exist? If it does, I really don't understand how!?

Yes it exists. Assume by "how" you mean "why". goto is extensively used
in machine-produced efficient C++ code.

--
Ioannis Vranos

http://www23.brinkster.com/noicys
Jul 23 '05 #7

P: n/a
Ioannis Vranos wrote:
Yes it exists. Assume by "how" you mean "why". goto is extensively used
in machine-produced efficient C++ code.


Please note Ioannis did not say "goto is efficient". It might be more
efficient than a well-structured function call; it might not.

Under the theory that a function takes time pushing variables onto a stack,
'goto' might generate a single branch opcode. However, that 'goto' might
live in a function that's now long enough to overflow the CPU cache. Several
small functions might have fit in the cache, making their specific function
calls faster.

--
Phlip
http://industrialxp.org/community/bi...UserInterfaces
Jul 23 '05 #8

P: n/a
On Thu, 24 Mar 2005 23:53:37 +0000 (UTC), "Michael"
<sl***********@hotmail.com> wrote:
I know I know its notoriously bad! I don't want to use it.


Why not? Goto is very useful since there is not labelled break. When
you have nested for in another for /for example/ the easiest way /and
elegant too/ to break from the external one is to use goto.

have a nice day
bye
--
Maciej "MACiAS" Pilichowski http://bantu.fm.interia.pl/

M A R G O T --> http://www.margot.cad.pl/
automatyczny tłumacz (wczesna wersja rozwojowa) angielsko-polski
Jul 23 '05 #9

P: n/a
Maciej Pilichowski wrote:
Michael wrote:
I know I know its notoriously bad! I don't want to use it.


Why not? Goto is very useful since there is not labelled break. When
you have nested for in another for /for example/ the easiest way /and
elegant too/ to break from the external one is to use goto.


or return.

Why is your function so long?

--
Phlip
http://industrialxp.org/community/bi...UserInterfaces
Jul 23 '05 #10

P: n/a
On Sat, 26 Mar 2005 12:35:13 GMT, "Phlip" <ph*******@yahoo.com> wrote:
>I know I know its notoriously bad! I don't want to use it. Why not? Goto is very useful since there is not labelled break. When
you have nested for in another for /for example/ the easiest way /and
elegant too/ to break from the external one is to use goto.


or return.


AFAIK return breaks the entire function ;-).
Why is your function so long?


I don't think that function 10-lines long is "so long". And I am
talking about pretty obvious

for (int x=0;x<width;++x)
for (int y=0;y<height;++y)
if (something())
break_the_x_loop;

and there is nice goto construction.

I just pointed the use of goto, if you are not convinced -- ok, it is
not Java, write your programs as you like.

have a nice day
bye

PS. On the other hand, such situations are rather rare -- in project
~40,000 lines long I had to use goto once :-)
--
Maciej "MACiAS" Pilichowski http://bantu.fm.interia.pl/

M A R G O T --> http://www.margot.cad.pl/
automatyczny tłumacz (wczesna wersja rozwojowa) angielsko-polski
Jul 23 '05 #11

P: n/a
Maciej Pilichowski wrote:
I don't think that function 10-lines long is "so long". And I am
talking about pretty obvious

for (int x=0;x<width;++x) { for (int y=0;y<height;++y) if (something())
break;

if(something())
break;
}

and there is nice goto construction.

Which can be avoided.

--
Ioannis Vranos

http://www23.brinkster.com/noicys

[I have set the word-wrapping at 90 characters. I am interested in hearing if it causes
inconvenience to anyone].
Jul 23 '05 #12

P: n/a
On Sun, 27 Mar 2005 09:18:00 +0200, Ioannis Vranos
<iv*@remove.this.grad.com> wrote:
Maciej Pilichowski wrote:
I don't think that function 10-lines long is "so long". And I am
talking about pretty obvious

for (int x=0;x<width;++x)

{
for (int y=0;y<height;++y)

if (something())
break;

if(something())
break;
}


You called something() twice, what if it has side-effects (like I/O)?

Yes, you can get round that with a boolean flag:

bool running = true;
for (int x = 0; running && x < width; ++x)
for (int y = 0; y < height; ++y)
if (something())
running = false;

but that is less obvious and in the case of more complicated loops can
obscure the actual flow.
and there is nice goto construction.


Which can be avoided.


Of course it can, so can most things. There are however occasions when
goto (and return in the middle of a function, which many ivory tower
computer scientists regard as nearly as bad) are the cleanest and most
maintainable constructions.

Just like the misquotation "Money is the root of all evil", saying that
all uses of goto are evil misses the point. Certainly /some/ uses of
goto are dangerousm just like /some/ uses of money, but the thing itself
is a tool nothing more.

As the C++ FAQ Lite says:

[6.14] What does the FAQ mean by "such and such is evil"?

It means such and such is something you should avoid most of the
time, but not something you should avoid all the time. For example,
you will end up using these "evil" things whenever they are "the
least evil of the evil alternatives." It's a joke, okay? Don't take
it too seriously.

...

Another thing: things labeled as "evil" (macros, arrays, pointers,
etc.) aren't always bad in all situations. When they are the "least
bad" of the alternatives, use them!

And as we know from the FDA, anything in excess can be "considered
harmful". Sugar, water, oxygen; goto, pointers, macros... People who
try to write everything as OO whether the problem domain matches it or
not. People who think "self-documenting code" means that all
identifiers have to be complete sentences. People insisting on "one
true way" in any field...

Fanaticism is the true evil. Death to all fanatics! The must be
moderation in all things (especially in moderation).

Chris C
Jul 23 '05 #13

P: n/a
Chris Croughton wrote:
You called something() twice, what if it has side-effects (like I/O)?

Yes, you can get round that with a boolean flag:

bool running = true;
for (int x = 0; running && x < width; ++x)
for (int y = 0; y < height; ++y)
if (something())
running = false;

but that is less obvious and in the case of more complicated loops can
obscure the actual flow.

or in this case:
return_type res;

for(int x=0; x<width; ++x)
{
for(int y=0; y<height; ++y)
{
res= something();

if(return_type)
break;
}
if(return_type)
break;
}
Of course it can, so can most things. There are however occasions when
goto (and return in the middle of a function, which many ivory tower
computer scientists regard as nearly as bad) are the cleanest and most
maintainable constructions.

Just like the misquotation "Money is the root of all evil", saying that
all uses of goto are evil misses the point. Certainly /some/ uses of
goto are dangerousm just like /some/ uses of money, but the thing itself
is a tool nothing more.

As the C++ FAQ Lite says:

[6.14] What does the FAQ mean by "such and such is evil"?

It means such and such is something you should avoid most of the
time, but not something you should avoid all the time. For example,
you will end up using these "evil" things whenever they are "the
least evil of the evil alternatives." It's a joke, okay? Don't take
it too seriously.

...

Another thing: things labeled as "evil" (macros, arrays, pointers,
etc.) aren't always bad in all situations. When they are the "least
bad" of the alternatives, use them!

However I haven't used goto since some time back in school, when I was checking
GWBASIC/QBasic then. So, this means it is not much needed, for regular application
programming at least.

I can understand its use on machine-produced C++ code and in a very desperate need for
performance, when all other alternatives are exhausted.

--
Ioannis Vranos

http://www23.brinkster.com/noicys

[I am using 90 characters word-wrapping - (800/640) *72= 90 or better described as:
(800/640) *80 - 10 for quotation= 90. If someone finds it inconvenient, please let me know].
Jul 23 '05 #14

P: n/a
On Sun, 27 Mar 2005 17:30:34 +0300, Ioannis Vranos
<iv*@remove.this.grad.com> wrote:
Chris Croughton wrote:
You called something() twice, what if it has side-effects (like I/O)?

Yes, you can get round that with a boolean flag:

bool running = true;
for (int x = 0; running && x < width; ++x)
for (int y = 0; y < height; ++y)
if (something())
running = false;
An extra break; is needed, or a test in te inner loop for running, I
chopped it down too far:

bool running = true;
for (int x = 0; running && x < width; ++x)
for (int y = 0; running && y < height; ++y)
if (something())
running = false;
but that is less obvious and in the case of more complicated loops can
obscure the actual flow.
or in this case:

return_type res;

for(int x=0; x<width; ++x)
{
for(int y=0; y<height; ++y)
{
res= something();

if(return_type)


You meant res, I assume <g>. And assuming that return_type evaluates to
non-zero if the exit is needed.
break;
}

if(return_type)
break;
}
Of course it can, so can most things. There are however occasions when
goto (and return in the middle of a function, which many ivory tower
computer scientists regard as nearly as bad) are the cleanest and most
maintainable constructions.
However I haven't used goto since some time back in school, when I was checking
GWBASIC/QBasic then. So, this means it is not much needed, for regular application
programming at least.


I don't use it either, but I do return from funtions in the middle, or
particularly near the start if conditions aren't met, which many people
regard as just as bad:

int func(int param)
{
if (param < 0)
return FAIL_VAL_1;
/* do stuff setting up conditions */
if (error_setting_conditions)
return FAIL_VAL_2;
/* do the actual stuff */
return SUCCESS_VAL;
}

However, I've seen goto used with good and clear effect as well.
I can understand its use on machine-produced C++ code and in a very desperate need for
performance, when all other alternatives are exhausted.


That's not the only time it's useful.

Chris C
Jul 23 '05 #15

P: n/a
In article <1111907881.61235@athnrd02>,
Ioannis Vranos <iv*@remove.this.grad.com> wrote:
Which can be avoided.


But is sometimes the best tool for the job. Ignoring your best tool
because of dogma is idiotic.
--
Mark Ping
em****@soda.CSUA.Berkeley.EDU
Jul 23 '05 #16

P: n/a
E. Mark Ping wrote:
In article <1111907881.61235@athnrd02>,
Ioannis Vranos <iv*@remove.this.grad.com> wrote:
Which can be avoided.

But is sometimes the best tool for the job. Ignoring your best tool
because of dogma is idiotic.


most of the time though, its an indicator that the design smells.

In the case of the example code within this thread, the nested for loops
are searching for something within an X & Y co-ordinate within a certain
width & height dimension.

When the target was originally placed at the co-ordinate, we could have
had the Dimension object keep a mapping co-ordinate -> target or target
-> co-ordinate, etc...

Then we could have queried and retrieved the target from the Dimension
Also, Goto's make refactoring very difficult.
Jul 23 '05 #17

P: n/a
Chris Croughton wrote:
On Sun, 27 Mar 2005 17:30:34 +0300, Ioannis Vranos
<iv*@remove.this.grad.com> wrote:

Chris Croughton wrote:

snipped

I don't use it either, but I do return from funtions in the middle, or
particularly near the start if conditions aren't met, which many people
regard as just as bad:

int func(int param)
{
if (param < 0)
return FAIL_VAL_1;
/* do stuff setting up conditions */
if (error_setting_conditions)
return FAIL_VAL_2;
/* do the actual stuff */
return SUCCESS_VAL;
}

There is nothing wrong with a function of that length having multiple
returns. Its very clear.

The problem with multiple returns within a single function is when the
functions are long. The longer a function to harder it is to see the
return points. By long I mean more than a hand full of lines, my
personal line per function limit is around 7. Comes from the human
minds ability to deal with groupings of 7 or less easily. (Its one
reason why your credit card numbers are bunched into groups of 4 digits,
and why telephone numbers typically have an area code and actual number
as two groupings).

Guard clauses as your example above are a great technique for aiding the
reader.

The worst Guard clauses are when the logic is inverted resulting in the
entire function body being indented excessively.

e.g. your code with badly implemented clauses.

int func(int param)
{
if (param > 0)
{
/* do stuff setting up conditions */
if (! error_setting_conditions )
{
/* do the actual stuff */
return SUCCESS_VAL;

} else
return FAIL_VAL_2;

} else
return FAIL_VAL_1;
}
I see this type of code all to often unfortunately.
Jul 23 '05 #18

P: n/a
Chris Croughton wrote:
return_type res;

for(int x=0; x<width; ++x)
{
for(int y=0; y<height; ++y)
{
res= something();

if(return_type)

You meant res, I assume <g>. And assuming that return_type evaluates to
non-zero if the exit is needed.

Yes.


break;
}

if(return_type)
break;
}
However I haven't used goto since some time back in school, when I was checking
GWBASIC/QBasic then. So, this means it is not much needed, for regular application
programming at least.

I don't use it either, but I do return from funtions in the middle, or
particularly near the start if conditions aren't met, which many people
regard as just as bad:

int func(int param)
{
if (param < 0)
return FAIL_VAL_1;
/* do stuff setting up conditions */
if (error_setting_conditions)
return FAIL_VAL_2;
/* do the actual stuff */
return SUCCESS_VAL;
}


I know some say that this is bad, I but do not agree with them. This is an unneeded
constraint, just to make our lives more difficult (or in other words, they think that by
imposing such restrictive rules will be able to protect bad programmers from bad programming).
However, I've seen goto used with good and clear effect as well.

I can understand the use of goto for the situations that I described. For example, in
application programming, in non-desperate for speed conditions, why should one use goto?

I can understand its use on machine-produced C++ code and in a very desperate need for
performance, when all other alternatives are exhausted.

That's not the only time it's useful.

May you say in what other conditions it is useful?

--
Ioannis Vranos

http://www23.brinkster.com/noicys

[I am using 90 characters word-wrapping - (800/640) *72= 90 or better described as:
(800/640) *80 - 10 for quotation= 90. If someone finds it inconvenient, please let me know].
Jul 23 '05 #19

P: n/a
In article <d2**********@news.freedom2surf.net>,
Andrew McDonagh <ne**@us.com> wrote:
most of the time though, its an indicator that the design smells.


In 10+ years of C/C++ coding I've never seen goto used except to exit
from an inner loop, which is where it's commonly recommended.
--
Mark Ping
em****@soda.CSUA.Berkeley.EDU
Jul 23 '05 #20

P: n/a
E. Mark Ping wrote:
In 10+ years of C/C++ coding I've never seen goto used except to exit
from an inner loop, which is where it's commonly recommended.


'goto' has been frowned upon for well over 10 years. However, if you have
never encountered any related design smell, consider yourself amazingly
lucky.

--
Phlip
http://industrialxp.org/community/bi...UserInterfaces
Jul 23 '05 #21

P: n/a
In article <AA****************@newssvr17.news.prodigy.com>,
Phlip <ph*******@yahoo.com> wrote:
E. Mark Ping wrote:
In 10+ years of C/C++ coding I've never seen goto used except to exit
from an inner loop, which is where it's commonly recommended.


'goto' has been frowned upon for well over 10 years. However, if you have
never encountered any related design smell, consider yourself amazingly
lucky.


Yes, Dijkstra's "Go To Statement Considered Harmful" was written
before C was created, yet people still unthinkingly carried the "goto
is bad" mantra beyond it's intent. The restrictions C places on goto
and the common advice (only use for escaping inner loops) pretty much
invalidates the dogma.
--
Mark Ping
em****@soda.CSUA.Berkeley.EDU
Jul 23 '05 #22

P: n/a
Phlip wrote:
E. Mark Ping wrote:

In 10+ years of C/C++ coding I've never seen goto used except to exit
from an inner loop, which is where it's commonly recommended.

'goto' has been frowned upon for well over 10 years. However, if you have
never encountered any related design smell, consider yourself amazingly
lucky.

seconded!
Jul 23 '05 #23

P: n/a
On Mon, 28 Mar 2005 04:24:31 +0300, Ioannis Vranos
<iv*@remove.this.grad.com> wrote:
Chris Croughton wrote:
I don't use it either, but I do return from funtions in the middle, or
particularly near the start if conditions aren't met, which many people
regard as just as bad:

int func(int param)
{
if (param < 0)
return FAIL_VAL_1;
/* do stuff setting up conditions */
if (error_setting_conditions)
return FAIL_VAL_2;
/* do the actual stuff */
return SUCCESS_VAL;
}


I know some say that this is bad, I but do not agree with them. This
is an unneeded constraint, just to make our lives more difficult (or
in other words, they think that by imposing such restrictive rules
will be able to protect bad programmers from bad programming).


But the same is true about blanket forbidding of goto. Unclear
programming is always bad, no language structure is inherrently bad
(well, OK, Intercal!) it's how you use it.
However, I've seen goto used with good and clear effect as well.


I can understand the use of goto for the situations that I described.
For example, in application programming, in non-desperate for speed
conditions, why should one use goto?


For clarity when appropriate.

void func(...)
{
for (...)
{
for (...)
{
for (...)
{
/* do stuff */
if (something_wrong)
goto cleanup;
/* do more stuff */
if (something_wrong)
goto cleanup;
}
}
}
cleanup:
/* do cleanup stuff */
}

It's a lot clearer than using flags to do it, and return isn't
appropriate because the 'cleanup' code would need to be duplicated which
is a maintenabce risk.
I can understand its use on machine-produced C++ code and in a very
desperate need for performance, when all other alternatives are
exhausted.


That's not the only time it's useful.


May you say in what other conditions it is useful?


Duh, breaking out of nested loops (see above). Which is where we came
in...

Chris C
Jul 23 '05 #24

P: n/a
Chris Croughton wrote:
I can understand the use of goto for the situations that I described.
For example, in application programming, in non-desperate for speed
conditions, why should one use goto?

For clarity when appropriate.

void func(...)
{
for (...)
{
for (...)
{
for (...)
{
/* do stuff */
if (something_wrong)
goto cleanup;
/* do more stuff */
if (something_wrong)
goto cleanup;
}
}
}
cleanup:
/* do cleanup stuff */
}

It's a lot clearer than using flags to do it, and return isn't
appropriate because the 'cleanup' code would need to be duplicated which
is a maintenabce risk.

This is better done with exceptions.

Duh, breaking out of nested loops (see above). Which is where we came
in...

In the above you use it to perform error handling.
--
Ioannis Vranos

http://www23.brinkster.com/noicys

[I am using 90 characters word-wrapping - (800/640) *72= 90 or better described as:
(800/640) *80 - 10 for quotation= 90. If someone finds it inconvenient, please let me know].
Jul 23 '05 #25

P: n/a
Chris Croughton wrote:
On Mon, 28 Mar 2005 04:24:31 +0300, Ioannis Vranos
<iv*@remove.this.grad.com> wrote:

Chris Croughton wrote:

I don't use it either, but I do return from funtions in the middle, or
particularly near the start if conditions aren't met, which many people
regard as just as bad:

int func(int param)
{
if (param < 0)
return FAIL_VAL_1;
/* do stuff setting up conditions */
if (error_setting_conditions)
return FAIL_VAL_2;
/* do the actual stuff */
return SUCCESS_VAL;
}
I know some say that this is bad, I but do not agree with them. This
is an unneeded constraint, just to make our lives more difficult (or
in other words, they think that by imposing such restrictive rules
will be able to protect bad programmers from bad programming).

But the same is true about blanket forbidding of goto.


I think one problem a lot of people have with it, is seeing it being
used/abused so often. Yes this should not mean we forbid it, but its use
should be very limited.

I had the great 'pleasure' to have to add a new feature to an existing
product, in which the original developer could not see an easy way out
of a 2 tier nested for loop with several If conditions inside. So they
used goto BAD_BOY:

He knew it was rubbish code, but time pressure meant he wanted something
out quickly. This code was supposed to remain in existence for a few
days until he could make it better. He even left a comment saying as much.

It lived for almost 2 years before finally being refactored away in
order to add functionality.
Unclear programming is always bad, no language structure is inherrently bad (well, OK, Intercal!) it's how you use it.

However, I've seen goto used with good and clear effect as well.


I can understand the use of goto for the situations that I described.
For example, in application programming, in non-desperate for speed
conditions, why should one use goto?

For clarity when appropriate.

void func(...)
{
for (...)
{
for (...)
{
for (...)
{
/* do stuff */
if (something_wrong)
goto cleanup;
/* do more stuff */
if (something_wrong)
goto cleanup;
}
}
}
cleanup:
/* do cleanup stuff */
}

It's a lot clearer than using flags to do it, and return isn't
appropriate because the 'cleanup' code would need to be duplicated which
is a maintenabce risk.


The problem I have with this type of code structure though, is that
whilst I can see on the screen the 3 nested for loops, the two If
conditions, the Do stuff AND finally the cleanup stuff, I would either
have to use a very small font, a very large monitor or scroll about to
see it all.

What I'm getting at, is that whilst it may appear to be 'clear' the
sheer amount of code means we can't easily see what is happening.

I'd also bet that there is significant duplication within the class(es)
.. If we have to do 3 nested for loops here, you can 'usually' bet
another place in the code base is doing the same nested loops.

Where as, if we separated 'query', 'retrieval' and 'do stuff to',
applied the appropriate design patterns (visitor, command what ever..)
then we usually end up with much smaller methods, no or little
duplication and just as easy and clear code.
Jul 23 '05 #26

P: n/a
Ioannis Vranos wrote:
Chris Croughton wrote:
I can understand the use of goto for the situations that I described.
For example, in application programming, in non-desperate for speed
conditions, why should one use goto?


For clarity when appropriate.

void func(...)
{
for (...)
{
for (...)
{
for (...)
{
/* do stuff */
if (something_wrong)
goto cleanup;
/* do more stuff */
if (something_wrong)
goto cleanup;
}
}
}
cleanup:
/* do cleanup stuff */
}

It's a lot clearer than using flags to do it, and return isn't
appropriate because the 'cleanup' code would need to be duplicated which
is a maintenabce risk.


This is better done with exceptions.


If the 'something wrong' is an exceptional case, then I'd agree
exceptions are appropriate. However, if the something wrong is not an
exceptional case, then using exceptions is really just another
interpretation/implementation of goto.

for example, it may be appropriate to throw an exception if one of the
function params is out of bounds.

if (param > arraySize) {
throw new IndexOutOfBoundsException();
}

where as, it might not be appropriate to throw an exception just because
something does not exist.

if (something == null) {
throw new NotFoundException();
}
Jul 23 '05 #27

P: n/a
Andrew McDonagh wrote:
for example, it may be appropriate to throw an exception if one of the
function params is out of bounds.

if (param > arraySize) {
throw new IndexOutOfBoundsException();
}

Yes.

where as, it might not be appropriate to throw an exception just because
something does not exist.

if (something == null) {
throw new NotFoundException();
}

Yes. It will not be appropriate if for example the null is signifying the expected end of
a sequence. But then, "something wrong" is not an accurate term to describe that.
That pseudocode was displaying error handling, with the use of goto to jump to the error
handling code, clearly substituting the exception handling mechanism.

--
Ioannis Vranos

http://www23.brinkster.com/noicys

[I am using 90 characters word-wrapping - (800/640) *72= 90 or better described as:
(800/640) *80 - 10 for quotation= 90. If someone finds it inconvenient, please let me know].
Jul 23 '05 #28

P: n/a
"Andrew McDonagh" <ne**@andrewcdonagh.f2s.com> wrote in message
news:d2**********@news.freedom2surf.net...
If the 'something wrong' is an exceptional case, then I'd agree exceptions
are appropriate. However, if the something wrong is not an exceptional
case, then using exceptions is really just another
interpretation/implementation of goto.


Not really.

There are (at least) three fundamental differences between exceptions and
goto:

1) The author of a throw statement does not need to know where the
exception will be caught.

2) It is possible to transfer information between the throw and the
corresponding catch.

3) It is possible to reach a catch only from code executed as part of
the corresponding try. It is possible to reach a label from anywhere in the
entire function (subject only to the restriction that you cannot jump from a
place where a variable is out of scope to a place where it is in scope).
Jul 23 '05 #29

P: n/a
Andrew McDonagh wrote:
where as, it might not be appropriate to throw an exception just because
something does not exist.

if (something == null) {
throw new NotFoundException();
}

About the not-exists stuff, as a return value, let me give you an example. .NET is *very*
high-level, OO and modern (meaning it uses all modern facilities). It uses exceptions
completely for error-handling, for every single error it throws an exception.

So if you want to establish a simple network connection for example and it fails, it
throws an exception. It doesn't return a null pointer. And I think this is the right approach.

Since we have exceptions, we do not need any error signalling through value return.
--
Ioannis Vranos

http://www23.brinkster.com/noicys

[I am using 90 characters word-wrapping - (800/640) *72= 90 or better described as:
(800/640) *80 - 10 for quotation= 90. If someone finds it inconvenient, please let me know].
Jul 23 '05 #30

P: n/a
On 2005-03-28 06:58:54 -0500, Chris Croughton <ch***@keristor.net> said:
On Mon, 28 Mar 2005 04:24:31 +0300, Ioannis Vranos
<iv*@remove.this.grad.com> wrote:

I can understand the use of goto for the situations that I described.
For example, in application programming, in non-desperate for speed
conditions, why should one use goto?


For clarity when appropriate.

void func(...)
{
for (...)
{
for (...)
{
for (...)
{
/* do stuff */
if (something_wrong)
goto cleanup;
/* do more stuff */
if (something_wrong)
goto cleanup;
}
}
}
cleanup:
/* do cleanup stuff */
}

It's a lot clearer than using flags to do it, and return isn't
appropriate because the 'cleanup' code would need to be duplicated which
is a maintenabce risk.


What about this (no duplication, exception safe, no potential for goto
jumping across constructors/destructors, etc.):

void func(...)
{
struct cleanup {
~cleanup() { /* do cleanup stuff */ }
} cleaner;

for (...)
{
for (...)
{
for (...)
{
/* do stuff */
if (something_wrong)
return; /* or throw*/

/* do more stuff */
if (something_wrong)
return; /* or throw*/
}
}
}
}

--
Clark S. Cox, III
cl*******@gmail.com

Jul 23 '05 #31

P: n/a
Clark S. Cox III wrote:
What about this (no duplication, exception safe, no potential for goto
jumping across constructors/destructors, etc.):

void func(...)
{
struct cleanup {
~cleanup() { /* do cleanup stuff */ }
} cleaner;

for (...)
{
for (...)
{
for (...)
{
/* do stuff */
if (something_wrong)
return; /* or throw*/

/* do more stuff */
if (something_wrong)
return; /* or throw*/
}
}
}
}


Try to pass local variables into ~cleanup(), to reliably clean them up. Your
little class rapidly gets very ugly - it grows a constructor, members, etc.

RAII works best when handles destruct themselves. Put another way,
destruction is an encapsulated detail of the handle, not of the function
using the handle.

--
Phlip
http://industrialxp.org/community/bi...UserInterfaces
Jul 23 '05 #32

P: n/a
Ioannis Vranos wrote:
So if you want to establish a simple network connection for example and
it fails, it throws an exception. It doesn't return a null pointer. And
I think this is the right approach.

Actually, it does not throw an exception on connection failure but a positive integer is
returned in connection success, and 0 in network failure.

However for all unexpected errors an exception is thrown, like when trying to open a file
with write access while it is being used by another application, for example.
--
Ioannis Vranos

http://www23.brinkster.com/noicys
Jul 23 '05 #33

P: n/a
Ioannis Vranos wrote:
So if you want to establish a simple network connection for example
and it fails, it throws an exception. It doesn't return a null
pointer. And I think this is the right approach.


Actually, it does not throw an exception on connection failure but a
positive integer is returned in connection success, and 0 in network
failure.

Actually I think it is a mistake of the book I am reading, it *does* throw an exception.
http://msdn.microsoft.com/library/en...necttopic2.asp

--
Ioannis Vranos

http://www23.brinkster.com/noicys
Jul 23 '05 #34

P: n/a
Phlip wrote:
Try to pass local variables into ~cleanup(), to reliably clean them up. Your
little class rapidly gets very ugly - it grows a constructor, members, etc.

RAII works best when handles destruct themselves. Put another way,
destruction is an encapsulated detail of the handle, not of the function
using the handle.


I prefer...

int cleanup_variable = 0; // Local vars needed for cleanup

class my_exception {};

try {
for (...)
{
for (...)
{
for (...)
{
// ...
if (something_wrong)
throw my_exception;

// ...
if (something_wrong)
throw my_exception;
}
}
}
} catch (my_exception&) {
// cleanup
// Optionally rethrow another exception
}

With a good compiler and optimizer, the run-time behavior of this code
should be equivalent to a goto to the outer block, with the additional
bonus that destructors for objects created in the for scope will be
properly called on the way out.

-dr
Jul 23 '05 #35

P: n/a
Dave Rahardja wrote:
Phlip wrote:
Try to pass local variables into ~cleanup(), to reliably clean them up. Your little class rapidly gets very ugly - it grows a constructor, members, etc.
RAII works best when handles destruct themselves. Put another way,
destruction is an encapsulated detail of the handle, not of the function
using the handle.


I prefer...

int cleanup_variable = 0; // Local vars needed for cleanup

class my_exception {};

try {
for (...)
{
for (...)
{
for (...)
{
// ...
if (something_wrong)
throw my_exception;

// ...
if (something_wrong)
throw my_exception;
}
}
}
} catch (my_exception&) {


catch(...), so called functions can throw safely.
// cleanup
// Optionally rethrow another exception
}

With a good compiler and optimizer, the run-time behavior of this code
should be equivalent to a goto to the outer block, with the additional
bonus that destructors for objects created in the for scope will be
properly called on the way out.


However, RAII works best when handles destruct themselves. Put another way,
destruction is an encapsulated detail of the handle, not of the function
using the handle.

--
Phlip
http://industrialxp.org/community/bi...UserInterfaces
Jul 23 '05 #36

P: n/a
Dave Rahardja wrote:
I prefer...

int cleanup_variable = 0; // Local vars needed for cleanup

class my_exception {};

try {
for (...)
{
for (...)
{
for (...)
{
// ...
if (something_wrong)
throw my_exception;

// ...
if (something_wrong)
throw my_exception;
}
}
}
} catch (my_exception&) {
// cleanup
// Optionally rethrow another exception
}

With a good compiler and optimizer, the run-time behavior of this code
should be equivalent to a goto to the outer block, with the additional
bonus that destructors for objects created in the for scope will be
properly called on the way out.

A style that I saw in a .NET book recently. I am just posting it here to see comments. :-)
for(...)
{
try
{
// Network connection attempt with object in the managed heap
}

catch(Exception *)
{
break;
}
}

I guess this makes sense for garbage collected objects in the heap.

--
Ioannis Vranos

http://www23.brinkster.com/noicys
Jul 23 '05 #37

This discussion thread is closed

Replies have been disabled for this discussion.