I have recently added a note about "init property is sometimes unsafe".

https://github.com/D-Programming-Language/d-programming-language.org/pull/201 

To reduce the risk, I have proposed an enhancement for .init property usage.

http://d.puremagic.com/issues/show_bug.cgi?id=8752 

Kenji Hara

2012/12/16 js.mdnq <js_adddot+mdng@gmail.com>
On Saturday, 15 December 2012 at 20:20:10 UTC, H. S. Teoh wrote:
On Sat, Dec 15, 2012 at 12:02:16PM -0800, Jonathan M Davis wrote:
On Saturday, December 15, 2012 11:45:10 H. S. Teoh wrote:
> Ironically enough, Andrei in the subsequent paragraph > discourages
> the use of such nested structs, whereas Walter's article > promotes
> the use of such Voldemort types as a "happy discovery". :)

No, the real irony is that it's Andrei who promoted them in the first
place. :)

Heh. :)



We _are_ finding some serious issues with them though (e.g. they don't
work with init and apparently can't work with init), and there has
been some discussion of ditching them due to such issues, but no
consensus has been reached on that.
[...]


Hmm, that's true. They can't possibly work with init: if you do
something like:

        auto func(int x) {
                struct V {
                        @property int value() { return x; }
                }
                return V();
        }
        auto v = func(123);
        auto u = v.init;        // <-- what happens here?
        writeln(u.value);       // <-- and here?

It seems that we'd have to make .init illegal on these Voldemort
structs. But that breaks consistency with the rest of the language that
every type must have an .init value.

Alternatively, .init can implicitly create a context where the value of
x is set to int.init. But this is unnecessary (it's supposed to be a
*Voldemort* type!) and very ugly (why are we creating a function's local
context when it isn't even being called?), not to mention useless
(u.value will return a nonsensical value).

Or, perhaps a less intrusive workaround, is to have .init set the hidden
context pointer to null, and you'll get a null deference when accessing
u.value. Which is not pretty either, since no pointers or references are
apparent in V.value; it's implicit.

It seems that the only clean way to do this is to use a class instead of
a struct, since the .init value will conveniently just be null, thereby
sidestepping the problem.


T


        auto func(int x) {
                struct V {
                        int value() { return x; }

                        @property V init() { return this; }

                }

                return V();
        }
        auto v = func(123);
        auto u = v.init;        // <-- what happens here?
        auto x = u.value;
        writeln(x);

If you add an init property then it is not null. I'm not sure if this is the correct behavior as I just jumped into this discussion and I'm not sure if I understand exactly what the problem with these types of structs are. (as far as I can tell they simply let you pass "sets" of data from a function rather easily while also keeping the details hidden(impossible to directly instantiate the struct since it is hidden inside the func)

In any case, when stepping through the code above, I noticed that init being called but resulting in u.value throwing a null exception. so I added an init property to V and then got the expected behavior. Probably too easy to be the correct solution but who knows ;)