www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - BUG: Break within While Statement with Try/Catch Inside

reply John Reimer <brk_6502 NO_SPA_M.yahoo.com> writes:
The D Programming Language manual states:

"break exits the innermost enclosing while, for, do, or switch statement,
resuming execution at the statement following it."

There appears to be a bug in which "break" does not exit the enclosing
"while" if the "break" is within a try{} statement.  Example:

==================================================
import std.stdio;

int main() {
        while (true) {
                try {
                if (true)
                        break;
                } catch (Object e) {
                if (true)
                        break;
                }
        }
        writefln("Exiting main successfully");  
        return 0;
}
=================================================

The first "break" causes a continuation of the while loop rather than an
exit of the while loop.  The last writefln() never gets executed.

Apparently the same problem does NOT exist in the "catch" statement as the
following code reveals:

==================================================
import std.stdio;

int main() {
        while (true) {
                try {
                throw new Object;
                } catch (Object e) {
                if (true)
                        break;
                }
        }
        writefln("Exiting main successfully");  
        return 0;
}
=================================================

In this instance the "break" in the catch statement actually exits the
"while" loop correctly.

This was a difficult bug to track down.  Needs fixing me thinks!

Later,

John
Jul 11 2004
next sibling parent "Kris" <someidiot earthlink.dot.dot.dot.net> writes:
"John Reimer" <brk_6502 NO_SPA_M.yahoo.com> wrote in message
news:cct6f0$cj6$1 digitaldaemon.com...
 The D Programming Language manual states:

 "break exits the innermost enclosing while, for, do, or switch statement,
 resuming execution at the statement following it."

 There appears to be a bug in which "break" does not exit the enclosing
 "while" if the "break" is within a try{} statement.  Example:

 ==================================================
 import std.stdio;

 int main() {
         while (true) {
                 try {
                 if (true)
                         break;
                 } catch (Object e) {
                 if (true)
                         break;
                 }
         }
         writefln("Exiting main successfully");
         return 0;
 }
 =================================================

 The first "break" causes a continuation of the while loop rather than an
 exit of the while loop.  The last writefln() never gets executed.

 Apparently the same problem does NOT exist in the "catch" statement as the
 following code reveals:

 ==================================================
 import std.stdio;

 int main() {
         while (true) {
                 try {
                 throw new Object;
                 } catch (Object e) {
                 if (true)
                         break;
                 }
         }
         writefln("Exiting main successfully");
         return 0;
 }
 =================================================

 In this instance the "break" in the catch statement actually exits the
 "while" loop correctly.

 This was a difficult bug to track down.  Needs fixing me thinks!
Yeah, I'll second that. It was wildly unexpected, most frustrating, and totally bogus all at the same time. The natural reaction is to blame anything *but* the compiler, which wasted the efforts of several in this instance. Here's what actually happened: 1) segfault in linux running mango test cases 2) lots of incremental isolation of code in various scattered places to see what might be the cause 3) some honing in upon a SocketListener which executes as an independent thread waiting for socket input 4) more time spent isolating code in a series of misguided attempts to figure out why linux sockets or threads are being a total pain 5) segfault noted in gcx.d indicated the heap is corrupted (whoopee) 6) even more effort wasted trying various wild goose chases, and constructing equivalence tests on Win32 7) eventual realization that the break; statement does absolutely nothing, zero, zilch, sweet fuck all, when executed within a try{} block (surrounded by an outer while). Hear ye, the seven deadly sins of working with Beta code ... that bogus codegen caused a socket to be read yet again after the OS had interrupted it because the host program was exiting. This caused some layer of socket.read() to trash part of the heap, causing gcx.d to segfault during termination cleanup. All reasonable efforts in the client code to avoid this situation were badly mauled by the lack of a logical execution path, due to the flaccid break statement. Times like this ..... ..... .....
Jul 12 2004
prev sibling parent reply John Reimer <brk_6502 NO_SPA_M.yahoo.com> writes:
Sooo... Walter, is this something you are going to fix in the next release?
Jul 13 2004
parent reply "Walter" <newshound digitalmars.com> writes:
"John Reimer" <brk_6502 NO_SPA_M.yahoo.com> wrote in message
news:cd2cks$309g$1 digitaldaemon.com...
 Sooo... Walter, is this something you are going to fix in the next
release? I guess people don't like having a 'break' out of a try block.
Jul 14 2004
parent reply David Medlock <amedlock nospam.org> writes:
Walter wrote:
 "John Reimer" <brk_6502 NO_SPA_M.yahoo.com> wrote in message
 news:cd2cks$309g$1 digitaldaemon.com...
 
Sooo... Walter, is this something you are going to fix in the next
release? I guess people don't like having a 'break' out of a try block.
Perhaps a 'break while;' statement similar to named break which would still allow leaving a try block? On second thought that seems a bit like extra baggage.....
Jul 16 2004
parent John Reimer <brk_6502 NOSP_AM.yahoo.com> writes:
David Medlock wrote:
 Walter wrote:
 
 "John Reimer" <brk_6502 NO_SPA_M.yahoo.com> wrote in message
 news:cd2cks$309g$1 digitaldaemon.com...

 Sooo... Walter, is this something you are going to fix in the next
release? I guess people don't like having a 'break' out of a try block.
Perhaps a 'break while;' statement similar to named break which would still allow leaving a try block? On second thought that seems a bit like extra baggage.....
I do not see why we need a "break" from a try block. If it stays in the language, then it will be impossible to get out of an enclosing while loop apart from a "return" or a labeled "break." A return is not always what is desired, and a goto is a hackish thing to be stuck with in such a situation. But that's beside the point, breaking from a try block is not part of the language definition. The documentation is clear about the 4 situations in which the break is effective: while, for, do, and switch statements. "break" should stay true to it's original definiton. Maybe the try/break was supposed to be a handy little sercret feature. But, if it is, it's sure a mean trick to play on the unsuspecting programmer.
Jul 16 2004