O
O.B.
Does C# support anything like PHP's break command that optionally
accepts a parameter specifying how many loops to break out of?
accepts a parameter specifying how many loops to break out of?
Does C# support anything like PHP's break command that optionally
accepts a parameter specifying how many loops to break out of?
O.B. said:Does C# support anything like PHP's break command that optionally
accepts a parameter specifying how many loops to break out of?
I've always considered Java 'labelled breaks' as just a way for the Java
designers to get 'goto' into Java without admitting defeat.
Especially when
you consider that you can use the labelled break to jump out of from any
braced block, not just loops.
Either way, I don't think there's anything inherently bad about
labeled "break" statements or "goto" statements. Sometimes they are
just what you need. Just remember not to aim at your foot when using
them.![]()
There's nothing bad in goto. I just love the longjmp() !!
Peter Duniho said:Personally, I'm not of the mind that "goto" statements are inherently
bad. They certainly can be misused, and may well be misused much more
than other language constructs. But they also have their place (and I
don't just mean as a replacement for falling through in "case" statements
).
Would you mind providing one such example?
Peter Duniho said:Well, one common scenario is error-handling. In some cases, it makes
sense to have a single exit point in a method so that things can be
cleaned up in a single block of code rather than repeating that code, or
some subset, throughout the method. Using a "goto" statement allows you
to place that cleanup in a single place (I generally put it at the end of
the method), jumping to it on an error, and otherwise falling straight
through.
Are there other ways to do that? Sure, especially in C# (which has
"using" as well as exceptions). But those alternatives don't always
result in code that's as readable.
And does the presence of those alternatives mean that a "goto" statement
is bad? No, not at all. Only someone who had a blanket objection to
using a "goto" statement for the sake of the objection would say it was.
The fact is, even if you never write a "goto" statement, you use "goto"s
all the time. As long as you're keeping the code structured as you use a
"goto" statement, you haven't done anything the compiler wouldn't do
anyway.
And if the use of the "goto" makes the code more readable, then that's an
advantage over shoe-horning your code into whatever alternative the
language would require to accomplish the same thing.
Sounds like structured exception handling.
At the risk of repeating myself, would you mind providing one such
example?
[...]The fact is, even if you never write a "goto" statement, you use
"goto"s all the time. As long as you're keeping the code structured as
you use a "goto" statement, you haven't done anything the compiler
wouldn't do anyway.
Um, okay. What does that have to do with using "goto" in a higher level
language? The reason language designers give us constructs such as "if"
and "for" and "try...catch...finally" is to make code more readable. The
fact that it compiles to "jump" statements is irrelevant to this
discussion.
I absolutely agree. Once again I ask, would you mind providing one such
example?
It's not very different, no. However, the way the code is formatted and
the actual performance of the code is not the same, and thus one may be
desirable over the other, depending on specific wants and needs of the
programmer.
I did. I'm sorry you are unable to conceptualize a piece of code that
shows how that would work. Since that's beyond your apparent ability to
grasp, here is a quick pseudo-code outline of what it would look like:
bool FDoSomething()
{
bool fRet = false;
// do something
if (something failed)
{
goto Failed;
}
// do something else
if (something else failed)
{
goto Failed;
}
// etc.
fRet = true;
Failed:
// cleanup (which may or may not use the success state to
// determine what to clean up)
return fRet;
}
There are other ways to represent the above, but a) they won't be as clear
and easy to read (one common alternative would be nested if()'s, which can
cause the indendation to get out of hand if there are many of them), and
b) one specific alternative would be to use exceptions to handle the
failure cases, but that's not at all desirable if the failure cases happen
with any sort of regularity, due to performance overhead.
Not that you should need any other examples, but a situation I ran into
recently was a series of conditional tests that involved some logic that
needed to be able to break out early when any condition tested true, but
continue testing more conditions otherwise. Normally, this would be
easily taken care of using if/else if/else logic. However, in this case
there were two issues that argued in favor of using "goto" statements:
1) In most cases, the affirmative action would have been empty for the
true case; the main goal was to eventually fall through to a common "we
met one of the conditions" section of the code. The final "if everything
failed" was a loop continue. Other than using gotos, the ways to
represent these would have been to have a series of empty true clauses for
the if() statements, or to reverse all the conditions, putting the loop
continue into each true clause rather than it being the final else clause.
2) In one of the if() statements, the code is more clear by breaking
the if() condition into two parts. But doing so breaks the chain of
if/else ifs.
By using "goto" statements for the affirmative cases, it allowed me to
write the code more simply as a sequence of individual if() statements,
where each condition represented exactly the higher-level design of the
code rather than the inverse, without using an exception with its overhead
to control program flow, and while still allowing me to break apart the
one if() in a way that made the intent of the code more clear.
Could the logic have been represented without using "goto" statements?
Absolutely. But it would not have been nearly as clear what the goal was,
or as efficient (had exception handling been used instead...frankly,
exception handling is a red herring as it deals with an entirely different
question).
[...]The fact is, even if you never write a "goto" statement, you use "goto"s
all the time. As long as you're keeping the code structured as you use
a "goto" statement, you haven't done anything the compiler wouldn't do
anyway.
Um, okay. What does that have to do with using "goto" in a higher level
language? The reason language designers give us constructs such as "if"
and "for" and "try...catch...finally" is to make code more readable. The
fact that it compiles to "jump" statements is irrelevant to this
discussion.
Well, I disagree. The question of structured programming is relatively
independent of the language. I can write a structured program in
assembly, and I can (with some difficulty) write an unstructured program
in a language that is designed to make structured programming easier.
But if you're going to invoke the question of "the reason language
designers give us...", then it seems to be a direct conclusion that since
the C# language designers provided us the "goto" statement, it obviously
must be useful and appropriate in certain situations.
I already did. But hopefully the elaboration above helps you understand
better.
Dilip said:I am not Peter Duniho but I can provide you an example from a real
world high-performance middle-ware product. I lifted this piece out
of the codebase of this product (http://www.zeroc.com)
Consider this snippet that listens on a socket:
public static void doListen(Socket socket, int backlog)
{
repeatListen:
try
{
socket.Listen(backlog);
}
catch(SocketException ex)
{
if(interrupted(ex))
{
goto repeatListen;
}
closeSocketNoThrow(socket);
throw new Ice.SocketException(ex);
}
}
public static bool interrupted(Win32Exception ex)
{
return ex.NativeErrorCode == WSAEINTR;
}
There are probably other ways to do this without using goto but you
will only end up obfuscating the intent of the code for some mythical
purity.
[...]
Another way to handle that situation is to create another function from
which you "return" when a failure condition occurs.
[...]By using "goto" statements for the affirmative cases, it allowed me to
write the code more simply as a sequence of individual if() statements,
where each condition represented exactly the higher-level design of the
code rather than the inverse, without using an exception with its
overhead to control program flow, and while still allowing me to break
apart the one if() in a way that made the intent of the code more clear.
Actually, you could create a boolean function to test conditions and a
seperate method to implement the success/failure logic.
[...]
This has the notable advantage of following the rule that "each method
should do only one thing, and do it well". ShouldDotIt() is the decision
process, while DoSomething() is the work being done.
Dilip said:I am not Peter Duniho but I can provide you an example from a real
world high-performance middle-ware product. I lifted this piece out
of the codebase of this product (http://www.zeroc.com)
Consider this snippet that listens on a socket:
public static void doListen(Socket socket, int backlog)
{
repeatListen:
try
{
socket.Listen(backlog);
}
catch(SocketException ex)
{
if(interrupted(ex))
{
goto repeatListen;
}
closeSocketNoThrow(socket);
throw new Ice.SocketException(ex);
}
}
public static bool interrupted(Win32Exception ex)
{
return ex.NativeErrorCode == WSAEINTR;
}
Peter Duniho said:[...]
Another way to handle that situation is to create another function from
which you "return" when a failure condition occurs.
Care to provide an example?![]()
Frankly, the things you've suggested so far are IMHO exactly the example
of hoop-jumping that I think is pointless when all you're trying to do is
avoid using a "goto" statement. They are appropriate techniques where
warranted, but if avoiding a "goto" statement is the only motivation,
that's just busy work.
[...]
This has the notable advantage of following the rule that "each method
should do only one thing, and do it well". ShouldDotIt() is the decision
process, while DoSomething() is the work being done.
That rule isn't bad per se. But it's far too vague, and taken to the
extreme would imply that any method should only ever have a single
statement, and that you should never have conditional clauses in the same
method with statements that produce results.
It is not in and of itself a justification for avoiding a "goto"
statement.
It's important to know when a rule either does not apply, or is overridden
by some other rule (such as not overcomplicating the code). Those pieces
of knowledge are every bit as important as knowing the rule in the first
place.
No. This is a common Win32 technique. Google it.
There is no "hoop-jumping" in the examples I provided.
Want to reply to this thread or ask your own question?
You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.