View mode: basic / threaded / horizontal-split · Log in · Help
December 15, 2012
Voldemort structs no longer work?
With latest git dmd:

	auto makeVoldemort(int x) {
		struct Voldemort {
			@property int value() { return x; }
		}
		return Voldemort();
	}
	void main() {
		auto v = makeVoldemort();
		writeln(v.value);
	}

Compile error:

	test.d(3): Error: function test.makeVoldemort.Voldemort.value cannot access frame of function test.makeVoldemort

Changing 'struct' to 'class' works. Is this deliberate, or is it a bug?
It is certainly inconsistent with Walter's article on Voldemort types,
which uses structs as examples.


T

-- 
You have to expect the unexpected. -- RL
December 15, 2012
Re: Voldemort structs no longer work?
On Saturday, 15 December 2012 at 18:38:29 UTC, H. S. Teoh wrote:
> With latest git dmd:
>
> 	auto makeVoldemort(int x) {
> 		struct Voldemort {
> 			@property int value() { return x; }
> 		}
> 		return Voldemort();
> 	}
> 	void main() {
> 		auto v = makeVoldemort();
> 		writeln(v.value);
> 	}
>
> Compile error:
>
> 	test.d(3): Error: function test.makeVoldemort.Voldemort.value 
> cannot access frame of function test.makeVoldemort
>
> Changing 'struct' to 'class' works. Is this deliberate, or is 
> it a bug?
> It is certainly inconsistent with Walter's article on Voldemort 
> types,
> which uses structs as examples.
>
>
> T

Pretty certain it's deliberate.  No closure is created for nested 
structs to access it's parent, complying with it's POD behaviour.

Regards,
Iain.
December 15, 2012
Re: Voldemort structs no longer work?
On Saturday, December 15, 2012 19:50:34 Iain Buclaw wrote:
> On Saturday, 15 December 2012 at 18:38:29 UTC, H. S. Teoh wrote:
> > With latest git dmd:
> > 	auto makeVoldemort(int x) {
> > 	
> > 		struct Voldemort {
> > 		
> > 			@property int value() { return x; }
> > 		
> > 		}
> > 		return Voldemort();
> > 	
> > 	}
> > 	void main() {
> > 	
> > 		auto v = makeVoldemort();
> > 		writeln(v.value);
> > 	
> > 	}
> > 
> > Compile error:
> > 	test.d(3): Error: function test.makeVoldemort.Voldemort.value
> > 
> > cannot access frame of function test.makeVoldemort
> > 
> > Changing 'struct' to 'class' works. Is this deliberate, or is
> > it a bug?
> > It is certainly inconsistent with Walter's article on Voldemort
> > types,
> > which uses structs as examples.
> > 
> > 
> > T
> 
> Pretty certain it's deliberate.  No closure is created for nested
> structs to access it's parent, complying with it's POD behaviour.

static nested structs don't have access to their outer scopes. Non-static 
structs do. This reeks of a bug.

- Jonathan M Davis
December 15, 2012
Re: Voldemort structs no longer work?
On Sat, Dec 15, 2012 at 11:31:22AM -0800, Jonathan M Davis wrote:
> On Saturday, December 15, 2012 19:50:34 Iain Buclaw wrote:
> > On Saturday, 15 December 2012 at 18:38:29 UTC, H. S. Teoh wrote:
> > > With latest git dmd:
> > > 	auto makeVoldemort(int x) {
> > > 	
> > > 		struct Voldemort {
> > > 		
> > > 			@property int value() { return x; }
> > > 		
> > > 		}
> > > 		return Voldemort();
> > > 	
> > > 	}
> > > 	void main() {
> > > 	
> > > 		auto v = makeVoldemort();
> > > 		writeln(v.value);
> > > 	
> > > 	}
> > > 
> > > Compile error:
> > > 	test.d(3): Error: function test.makeVoldemort.Voldemort.value
> > > 
> > > cannot access frame of function test.makeVoldemort
> > > 
> > > Changing 'struct' to 'class' works. Is this deliberate, or is it a
> > > bug?  It is certainly inconsistent with Walter's article on
> > > Voldemort types, which uses structs as examples.
[...]
> > Pretty certain it's deliberate.  No closure is created for nested
> > structs to access it's parent, complying with it's POD behaviour.
> 
> static nested structs don't have access to their outer scopes.
> Non-static structs do. This reeks of a bug.
[...]

Found the reference in TDPL, §7.1.9 (p.263):

	Nested structs embed the magic "frame pointer" that allows them
	to access outer values such as a and b in the example above.
	[...] If you want to define a nested struct without that
	baggage, just prefix struct with static in the definition of
	Local, which makes Local a regular struct and consequently
	prevents it from accessing a and b.

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". :)

Anyway, filed a bug:

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


T

-- 
Nobody is perfect.  I am Nobody. -- pepoluan, GKC forum
December 15, 2012
Re: Voldemort structs no longer work?
On Sat, Dec 15, 2012 at 11:45:10AM -0800, H. S. Teoh wrote:
[...]
> Found the reference in TDPL, §7.1.9 (p.263):
> 
> 	Nested structs embed the magic "frame pointer" that allows them
> 	to access outer values such as a and b in the example above.
> 	[...] If you want to define a nested struct without that
> 	baggage, just prefix struct with static in the definition of
> 	Local, which makes Local a regular struct and consequently
> 	prevents it from accessing a and b.
> 
> 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". :)
> 
> Anyway, filed a bug:
> 
> 	http://d.puremagic.com/issues/show_bug.cgi?id=9162
[...]

Also, according to http://dlang.org/struct.html:

	A nested struct is a struct that is declared inside the scope of
	a function or a templated struct that has aliases to local
	functions as a template argument. Nested structs have member
	functions. It has access to the context of its enclosing scope
	(via an added hidden field).


T

-- 
If you compete with slaves, you become a slave. -- Norbert Wiener
December 15, 2012
Re: Voldemort structs no longer work?
On 15 December 2012 19:45, H. S. Teoh <hsteoh@quickfur.ath.cx> wrote:

> On Sat, Dec 15, 2012 at 11:31:22AM -0800, Jonathan M Davis wrote:
> > On Saturday, December 15, 2012 19:50:34 Iain Buclaw wrote:
> > > On Saturday, 15 December 2012 at 18:38:29 UTC, H. S. Teoh wrote:
> > > > With latest git dmd:
> > > >   auto makeVoldemort(int x) {
> > > >
> > > >           struct Voldemort {
> > > >
> > > >                   @property int value() { return x; }
> > > >
> > > >           }
> > > >           return Voldemort();
> > > >
> > > >   }
> > > >   void main() {
> > > >
> > > >           auto v = makeVoldemort();
> > > >           writeln(v.value);
> > > >
> > > >   }
> > > >
> > > > Compile error:
> > > >   test.d(3): Error: function test.makeVoldemort.Voldemort.value
> > > >
> > > > cannot access frame of function test.makeVoldemort
> > > >
> > > > Changing 'struct' to 'class' works. Is this deliberate, or is it a
> > > > bug?  It is certainly inconsistent with Walter's article on
> > > > Voldemort types, which uses structs as examples.
> [...]
> > > Pretty certain it's deliberate.  No closure is created for nested
> > > structs to access it's parent, complying with it's POD behaviour.
> >
> > static nested structs don't have access to their outer scopes.
> > Non-static structs do. This reeks of a bug.
> [...]
>
> Found the reference in TDPL, §7.1.9 (p.263):
>
>         Nested structs embed the magic "frame pointer" that allows them
>         to access outer values such as a and b in the example above.
>         [...] If you want to define a nested struct without that
>         baggage, just prefix struct with static in the definition of
>         Local, which makes Local a regular struct and consequently
>         prevents it from accessing a and b.
>
> 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". :)
>
> Anyway, filed a bug:
>
>         http://d.puremagic.com/issues/show_bug.cgi?id=9162
>
>
If it is one, it's a bug in FuncDeclaration::getLevel.


-- 
Iain Buclaw

*(p < e ? p++ : p) = (c & 0x0f) + '0';
December 15, 2012
Re: Voldemort structs no longer work?
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. :)

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.

- Jonathan M Davis
December 15, 2012
Re: Voldemort structs no longer work?
On 15 December 2012 19:58, Iain Buclaw <ibuclaw@ubuntu.com> wrote:

> On 15 December 2012 19:45, H. S. Teoh <hsteoh@quickfur.ath.cx> wrote:
>
>> On Sat, Dec 15, 2012 at 11:31:22AM -0800, Jonathan M Davis wrote:
>> > On Saturday, December 15, 2012 19:50:34 Iain Buclaw wrote:
>> > > On Saturday, 15 December 2012 at 18:38:29 UTC, H. S. Teoh wrote:
>> > > > With latest git dmd:
>> > > >   auto makeVoldemort(int x) {
>> > > >
>> > > >           struct Voldemort {
>> > > >
>> > > >                   @property int value() { return x; }
>> > > >
>> > > >           }
>> > > >           return Voldemort();
>> > > >
>> > > >   }
>> > > >   void main() {
>> > > >
>> > > >           auto v = makeVoldemort();
>> > > >           writeln(v.value);
>> > > >
>> > > >   }
>> > > >
>> > > > Compile error:
>> > > >   test.d(3): Error: function test.makeVoldemort.Voldemort.value
>> > > >
>> > > > cannot access frame of function test.makeVoldemort
>> > > >
>> > > > Changing 'struct' to 'class' works. Is this deliberate, or is it a
>> > > > bug?  It is certainly inconsistent with Walter's article on
>> > > > Voldemort types, which uses structs as examples.
>> [...]
>> > > Pretty certain it's deliberate.  No closure is created for nested
>> > > structs to access it's parent, complying with it's POD behaviour.
>> >
>> > static nested structs don't have access to their outer scopes.
>> > Non-static structs do. This reeks of a bug.
>> [...]
>>
>> Found the reference in TDPL, §7.1.9 (p.263):
>>
>>         Nested structs embed the magic "frame pointer" that allows them
>>         to access outer values such as a and b in the example above.
>>         [...] If you want to define a nested struct without that
>>         baggage, just prefix struct with static in the definition of
>>         Local, which makes Local a regular struct and consequently
>>         prevents it from accessing a and b.
>>
>> 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". :)
>>
>> Anyway, filed a bug:
>>
>>         http://d.puremagic.com/issues/show_bug.cgi?id=9162
>>
>>
> If it is one, it's a bug in FuncDeclaration::getLevel.
>
>
And if it isn't FuncDeclaration::getLevel(), then it is a bug because the
struct Voldemort does not represent itself as a nested type.

-- 
Iain Buclaw

*(p < e ? p++ : p) = (c & 0x0f) + '0';
December 15, 2012
Re: Voldemort structs no longer work?
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

-- 
If creativity is stifled by rigid discipline, then it is not true creativity.
December 15, 2012
Re: Voldemort structs no longer work?
On Saturday, December 15, 2012 12:18:21 H. S. Teoh wrote:
> 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.

That would incur unnecessary overhead and probably break all kinds of code, 
because they're then reference types instead of value types, and a _lot_ of 
code doesn't use save propperly. If structs can't do what we need as Voldemort 
types, it's just better to make it so that they're not Voldemort types. 
Voldemort types are a cute idea, and in principle are great, but I don't think 
that it's worth fighting to keep them if they have problems.

- Jonathan M Davis
« First   ‹ Prev
1 2
Top | Discussion index | About this forum | D home