www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Immutable + goto?

reply dsimcha <dsimcha yahoo.com> writes:
import std.stdio;

uint bar = 0;

void main() {
    start:
    immutable uint foo = bar;
    bar++;
    writeln(foo);
    goto start;
}

foo changes in this case.  Is this a real bug, or is it considered undefined
behavior to use goto in this way?
Mar 19 2009
next sibling parent reply Frits van Bommel <fvbommel REMwOVExCAPSs.nl> writes:
dsimcha wrote:
 import std.stdio;
 
 uint bar = 0;
 
 void main() {
     start:
     immutable uint foo = bar;
     bar++;
     writeln(foo);
     goto start;
 }
 
 foo changes in this case.  Is this a real bug, or is it considered undefined
 behavior to use goto in this way?

I disagree: foo doesn't change there :รพ. Declaring a local variable like that actually creates a new scope behind the scenes, containing everything up to '}' (taking nesting into account, of course). This means the label is outside the scope of foo, and foo gets "destroyed" when the goto jumps out of it. A "new" foo is created (with a different value) when the program enters its scope. This is basically the same as: ----- while (true) { immutable uint foo = bar; bar++; writefln(foo); } ----- or even: ----- while (true) { void nested_fn(uint foo) { bar++; writefln(foo); } nested_fn(bar); } ----- which show the behavior more clearly.
Mar 19 2009
parent reply Max Samukha <samukha voliacable.com.removethis> writes:
On Thu, 19 Mar 2009 16:58:27 +0100, Frits van Bommel
<fvbommel REMwOVExCAPSs.nl> wrote:

dsimcha wrote:
 import std.stdio;
 
 uint bar = 0;
 
 void main() {
     start:
     immutable uint foo = bar;
     bar++;
     writeln(foo);
     goto start;
 }
 
 foo changes in this case.  Is this a real bug, or is it considered undefined
 behavior to use goto in this way?

I disagree: foo doesn't change there :?. Declaring a local variable like that actually creates a new scope behind the scenes, containing everything up to '}' (taking nesting into account, of course). This means the label is outside the scope of foo, and foo gets "destroyed" when the goto jumps out of it. A "new" foo is created (with a different value) when the program enters its scope. This is basically the same as: ----- while (true) { immutable uint foo = bar; bar++; writefln(foo); } ----- or even: ----- while (true) { void nested_fn(uint foo) { bar++; writefln(foo); } nested_fn(bar); } ----- which show the behavior more clearly.

Then this is a really weird behavior: void main() { start: //int j = bar; scope(exit) writefln("exit"); writefln(bar); bar++; if (bar == 10) return; goto start; } scope(exit) is not called at all when the local is commented out and called 10 times, otherwise. This implicit scope looks more like a bug or misfeature to me. Not calling scope(exit) if there is no variable declared is definitely a bug.
Mar 19 2009
parent Gide Nwawudu <gide btinternet.com> writes:
On Thu, 19 Mar 2009 21:01:40 +0200, Max Samukha
<samukha voliacable.com.removethis> wrote:

Then this is a really weird behavior:

void main()
{
start:
    //int j = bar;
    scope(exit)
        writefln("exit");
    writefln(bar);
    bar++;
    if (bar == 10)
        return;
    goto start;
}

scope(exit) is not called at all when the local is commented out and
called 10 times, otherwise. This implicit scope looks more like a bug
or misfeature to me. Not calling scope(exit) if there is no variable
declared is definitely a bug.

See below, added comment. http://d.puremagic.com/issues/show_bug.cgi?id=1087 Gide
Mar 19 2009
prev sibling parent Derek Parnell <derek psych.ward> writes:
On Thu, 19 Mar 2009 15:07:33 +0000 (UTC), dsimcha wrote:

 import std.stdio;
 
 uint bar = 0;
 
 void main() {
     start:
     immutable uint foo = bar;
     bar++;
     writeln(foo);
     goto start;
 }
 
 foo changes in this case.  Is this a real bug, or is it considered undefined
 behavior to use goto in this way?

Hopefully I'm wrong but I believe that this is not a bug. It is incorrect coding style. As I've recently worked out from Walter's discussions, the compiler does NOT enforce immutabilty or CAUSE things to be immutable. You should only declare immutable those things that you know actually are already immutable - like literals or stuff which is only ever assigned to once. On the other hand, I think this should be a bug. -- Derek Parnell Melbourne, Australia skype: derek.j.parnell
Mar 19 2009