Lazy evaluation

BCS BCS at pathlink.com
Wed Jun 27 15:02:43 PDT 2007


Lutger wrote:
> BCS wrote:
> 
>> Lutger wrote:
>>
>>> BCS wrote:
>>>
>>>> OF wrote:
>>>>
>>>>> It hints at lazyexp not being valid after the function has ended, 
>>>>> which makes it quite different from delegates.
>>>>
>>>>
>>>>
>>>> This is the /exact/ behavior of delegate liters and delegates formed 
>>>> from nested functions. They are invalid after the function call they 
>>>> are from returns. This is because the delegate caries a pointer to 
>>>> the stack frame of the surrounding function.
>>>
>>>
>>>
>>> Yeah, but only when you access some variables through this pointer 
>>> right?
>>
>>
>> I would assume so but there might be some hidden reads that could 
>> cause problems.
> 
> 
> Could you elaborate? I see nothing in the spec that says it's legal or 
> not. If there are problems with this, I think that should be clearly 
> stated.

I known of no cases where hidden read/writes happen, but unless the spec 
says so, I would not assume they don't happen if I could avoid it. The 
spec does say that a delegate to a nested function is invalid after the 
function returns (note nothing about if it access anything).

<start rant>

This is one reason where I would really like to see explicit contexts 
for delegate literals

class C{
	int i;
	int j;
}

void main(){
	C c = new C;
	void delegate (int, int) set = c.(int k, int l){
			i=k;
			j=l; // access any public parts of the thing
			};

		// delegate literal without risk of stack corruption
	void delegate() action = null.{someGlobalAction();};

	int i = 5;
	bool delegate(int) test = i.(int j){
			return this == j; // why not int for context?
			};		// sizeof(int) == sizeof(void*)

		// now how about 32bit structs by value?
	struct foo
	{
		short a;
		char b;
		byte c;
	}
	static assert(sizeof(foo) == sizeof(void*));

	foo dat = foo(45, 'c', 222)
	int delegate() go_v = dat.{return  a+b+c;};

		// now by reference
	int delegate() go_p = (&dat).{return  a+b+c;};

	dat.a = 0;
	dat.b = '\0';
	dat.c = 0;
	assert(go_v != 0);
	assert(go_p == 0);
}



More information about the Digitalmars-d mailing list