Thread overview
[Issue 827] New: Trying to break out of a labelled BlockStatement breaks out of a for loop at its beginning
Jan 10, 2007
d-bugmail
Apr 05, 2007
d-bugmail
Jun 23, 2008
d-bugmail
Jun 23, 2008
d-bugmail
January 10, 2007
http://d.puremagic.com/issues/show_bug.cgi?id=827

           Summary: Trying to break out of a labelled BlockStatement breaks
                    out of a for loop at its beginning
           Product: D
           Version: 1.00
          Platform: PC
        OS/Version: Windows
            Status: NEW
          Keywords: accepts-invalid, wrong-code
          Severity: normal
          Priority: P2
         Component: DMD
        AssignedTo: bugzilla@digitalmars.com
        ReportedBy: smjg@iname.com


----------
import std.stdio;

void main() {
    block: {
        for (int i = 0; i < 10; i++) {
            if (i == 5) break block;
        }
        writefln("Within block");
    }
    writefln("Outside block");
}
----------
Within block
Outside block
----------

I was expecting it to print only "Outside block".  However, according to the spec, the code shouldn't compile:

http://www.digitalmars.com/d/statement.html
"If break is followed by Identifier, the Identifier  must be the label of an
enclosing while, for, do or switch statement, and that statement is exited. It
is an error if there is no such statement."

The restriction to while, for, do or switch seems arbitrary, but still....


-- 

April 05, 2007
http://d.puremagic.com/issues/show_bug.cgi?id=827


thomas-dloop@kuehne.cn changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
  BugsThisDependsOn|                            |199
         OS/Version|Windows                     |All

Bug 827 depends on bug 199, which changed state.

Bug 199 Summary: Label causes scope to collapse into parent http://d.puremagic.com/issues/show_bug.cgi?id=199

           What    |Old Value                   |New Value
----------------------------------------------------------------------------
             Status|REOPENED                    |RESOLVED
         Resolution|                            |WORKSFORME
             Status|RESOLVED                    |REOPENED
         Resolution|WORKSFORME                  |



------- Comment #1 from thomas-dloop@kuehne.cn  2007-04-05 05:26 -------
I'm not sure this is the same as issue 199 but 199's "collapsing scope" looks like the root cause.

Added to DStress as http://dstress.kuehne.cn/nocompile/b/break_13_A.d http://dstress.kuehne.cn/nocompile/b/break_13_B.d


-- 

June 23, 2008
http://d.puremagic.com/issues/show_bug.cgi?id=827


bugzilla@digitalmars.com changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
         Resolution|                            |WONTFIX




------- Comment #2 from bugzilla@digitalmars.com  2008-06-23 17:10 -------
It works as spec'd, and you're right it is the same issue as 199. Won't change behavior for the same reason. Note that if you write it as (inserting an if statement):

import std.stdio;

void main() {
    block: if (1) {
        for (int i = 0; i < 10; i++) {
            if (i == 5) break block;
        }
        writefln("Within block");
    }
    writefln("Outside block");
}

it won't compile per the spec.


-- 

June 23, 2008
http://d.puremagic.com/issues/show_bug.cgi?id=827


smjg@iname.com changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|RESOLVED                    |REOPENED
         Resolution|WONTFIX                     |




------- Comment #3 from smjg@iname.com  2008-06-23 18:04 -------
(In reply to comment #2)
> It works as spec'd,

No it doesn't.  The statement from the spec that I already quoted is still there, word for word.

> and you're right it is the same issue as 199.

Maybe within the compiler, but not insofar as according to the language, the label is of the BlockStatement not of the ForStatement therein.  What the label labels and whether the BlockStatement opens a new scope or not are essentially distinct concepts.

> Won't change behavior for the same reason.

If you're referring to bug 199 comment 6, neither point seems to me to apply here:

> I don't want to change this because it could break existing code,

Somebody who wants the existing behaviour of my code example can just use

void main() {
    block: for (int i = 0; i < 10; i++) {
        if (i == 5) break block;
    }
    writefln("Within block");
    writefln("Outside block");
}

so what's there to break?

> and there doesn't seem to be a compelling reason to do so.

I certainly think there is: the nasty shock a programmer gets on trying this
code, expecting it to (a) be legal (b) if so, behave in a way that makes
intuitive sense.

(In reply to comment #2)
> Note that if you write it as (inserting an if statement):
<snip>
> it won't compile per the spec.

Maybe.  But is this really relevant?  Nobody's going to do this just to make the compiler catch the error, since doing so would imply that the coder's own eyes have already caught the error.


--