March 02, 2016
import std.stdio : writeln;

struct foo
{
    long* bar;

    this (long l)
    {
        long d = l;
        bar = &d;
    }
}

int main()
{
    foo f = foo(12345);
    writeln(*f.bar);
    //writefoo(f);
    writeln(*f.bar);

    return 0;
}

void writefoo(foo f)
{
    writeln(*f.bar);
}


If I compile this with dmd, I get the obvious output
12345
12345

however, if I uncomment the line writefoo(f);, I get
12345
140724376879320
140724376879320

(the second number changes each time, and appears to be a memory address)
Stranger still, if I change the constructor to
this (long l)
{
    writeln("wtf?");
    long d = l;
    bar = &d;
}

I get
wtf?
12345
12289
4422212

The second and third numbers don't change

Why does this happen? Were these functional programming guys right about impure functions having side effects after all?
March 01, 2016
On 03/01/2016 05:11 PM, asdf wrote:
> import std.stdio : writeln;
>
> struct foo
> {
>      long* bar;
>
>      this (long l)
>      {
>          long d = l;
>          bar = &d;

Unfortunately, 'bar' is pointing at the temporary stack-based variable 'd'.

>      }
> }
>
> int main()
> {
>      foo f = foo(12345);
>      writeln(*f.bar);

That's undefined behavior because f.bar is pointing at a dead object (d).

>      //writefoo(f);
>      writeln(*f.bar);
>
>      return 0;
> }
>
> void writefoo(foo f)
> {
>      writeln(*f.bar);
> }
>
>
> If I compile this with dmd, I get the obvious output
> 12345
> 12345

Yeah, undefined behavior sometimes produces "obvious" outputs. ;)

Ali