Thread overview
Immutable + goto?
Mar 19, 2009
dsimcha
Mar 19, 2009
Frits van Bommel
Mar 19, 2009
Max Samukha
Mar 19, 2009
Gide Nwawudu
Mar 19, 2009
Derek Parnell
March 19, 2009
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?
March 19, 2009
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.
March 19, 2009
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.
March 19, 2009
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
March 19, 2009
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