Re: Gotchas for returning values from blocks
On Monday, 13 June 2016 at 14:16:58 UTC, jmh530 wrote: So returning a reference to something on the stack is a bad idea, but copying the value would be fine. This is easy enough to get wrong elsewhere too. I recall having an issue with a foreach, until I added a 'ref' to it. Looking at the addresses all pointing to the same spot (the temporary) which can add curiously subtle bugs, or blatantly obvious ones.
Re: Gotchas for returning values from blocks
On Monday, 13 June 2016 at 01:41:07 UTC, Mike Parker wrote: Everything works fine in your example because 'new' always allocates on the heap. Anything allocated on the stack is not guaranteed to be valid after the scope exits: struct Foo { int baz; ~this() { baz = 1; } } void main() { import std.stdio : writeln; Foo* foo; { Foo bar = Foo(10); foo = } //bar is now out of scope assert(foo.baz == 10); } Struct constructors are always run when exiting a scope. More importantly, the pointer to bar is only valid until the stack address where it lives is overwritten by another stack allocation. In this example, there's no chance for that to happen before I access it, but it could happen at any time. So returning a reference to something on the stack is a bad idea, but copying the value would be fine.
Re: Gotchas for returning values from blocks
On Sunday, 12 June 2016 at 18:24:58 UTC, jmh530 wrote: garbage collected variable and assign it to it. Everything seems to work fine. I'm just not sure if there are any gotchas to be aware of. class Foo { int baz = 2; } void main() { import std.stdio : writeln; Foo foo; { Foo bar = new Foo(); foo = bar; } //bar is now out of scope assert(foo.baz == 2); } Everything works fine in your example because 'new' always allocates on the heap. Anything allocated on the stack is not guaranteed to be valid after the scope exits: struct Foo { int baz; ~this() { baz = 1; } } void main() { import std.stdio : writeln; Foo* foo; { Foo bar = Foo(10); foo = } //bar is now out of scope assert(foo.baz == 10); } Struct constructors are always run when exiting a scope. More importantly, the pointer to bar is only valid until the stack address where it lives is overwritten by another stack allocation. In this example, there's no chance for that to happen before I access it, but it could happen at any time.
Re: Gotchas for returning values from blocks
On Sunday, 12 June 2016 at 19:30:49 UTC, Era Scarecrow wrote: On Sunday, 12 June 2016 at 18:24:58 UTC, jmh530 wrote: I'm just not sure if there are any gotchas to be aware of. Aside from forgetting it's it's own block, you might add a return statement to it and leave the entire function. Or forget what's in what scope (assuming you do more than 1-2 pages of code per function). They do sorta behave like inlined void delegate functions (skip the call & heavy stack management). Unless there's a good reason for using blocks I don't see the need, since you will likely use inner scopes in if statements and the like anyways. Good points. Thanks for the reply.
Re: Gotchas for returning values from blocks
On Sunday, 12 June 2016 at 18:24:58 UTC, jmh530 wrote: I'm just not sure if there are any gotchas to be aware of. Aside from forgetting it's it's own block, you might add a return statement to it and leave the entire function. Or forget what's in what scope (assuming you do more than 1-2 pages of code per function). They do sorta behave like inlined void delegate functions (skip the call & heavy stack management). Unless there's a good reason for using blocks I don't see the need, since you will likely use inner scopes in if statements and the like anyways.