Voldemort structs no longer work?

js.mdnq js_adddot+mdng at gmail.com
Sun Dec 16 00:03:14 PST 2012


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 ;)


More information about the Digitalmars-d mailing list