Thread overview
"template with auto ref" experiment
Feb 04, 2017
Alex
Feb 04, 2017
kinke
Feb 05, 2017
Alex
Feb 04, 2017
Ali Çehreli
Feb 05, 2017
Alex
February 04, 2017
Having read this
https://dlang.org/spec/template.html#auto-ref-parameters

I tried to do something like this

// Code starts here
void main()
{
	initStruct iSb;
	iSb.var = 3;
	A b = A(iSb);
	assert(*b.myVar == 3); // this works
	iSb.var = 4;
	assert(*b.myVar == 4); // as expected
	
	b = A(initStruct(5)); // how does
	assert(*b.myVar == 5); // this work?
}

struct A
{
	@disable this();
	size_t* myVar;
	this()(auto ref initStruct iS) @nogc
	{
		import core.stdc.stdio;
		__traits(isRef, iS) ? printf("ref case\n") : printf("value case");
		
		myVar = &iS.var;
		
		/* // This treatment is not needed?
		if(__traits(isRef, iS))
		{
			myVar = &iS.var;
		}
		else
		{
			myVar = new size_t(iS.var);
		}
		*/	
	}
}

struct initStruct
{
	size_t var;
}
// Code ends here

All asserts pass. But the question is how it is possible to avoid the allocation of memory for the member var of the struct A in the second case. Is the input remains somewhere and I'm not aware of this?
By the way, I find the fact very cool. I'm just wondering, whether I'm doing something unsecure...
February 04, 2017
On Saturday, 4 February 2017 at 14:33:12 UTC, Alex wrote:
> Having read this
> https://dlang.org/spec/template.html#auto-ref-parameters
>
> I tried to do something like this
>
> // Code starts here
> void main()
> {
> 	initStruct iSb;
> 	iSb.var = 3;
> 	A b = A(iSb);
> 	assert(*b.myVar == 3); // this works
> 	iSb.var = 4;
> 	assert(*b.myVar == 4); // as expected
> 	
> 	b = A(initStruct(5)); // how does
> 	assert(*b.myVar == 5); // this work?
> }
>
> struct A
> {
> 	@disable this();
> 	size_t* myVar;
> 	this()(auto ref initStruct iS) @nogc
> 	{
> 		import core.stdc.stdio;
> 		__traits(isRef, iS) ? printf("ref case\n") : printf("value case");
> 		
> 		myVar = &iS.var;
> 		
> 		/* // This treatment is not needed?
> 		if(__traits(isRef, iS))
> 		{
> 			myVar = &iS.var;
> 		}
> 		else
> 		{
> 			myVar = new size_t(iS.var);
> 		}
> 		*/	
> 	}
> }
>
> struct initStruct
> {
> 	size_t var;
> }
> // Code ends here
>
> All asserts pass. But the question is how it is possible to avoid the allocation of memory for the member var of the struct A in the second case. Is the input remains somewhere and I'm not aware of this?
> By the way, I find the fact very cool. I'm just wondering, whether I'm doing something unsecure...

It most likely only works because the dangling pointer points into yet untouched stack. Trying to öet a normal by-value parameter or local variable escape this way should produce an error, but apparently it's not done for `auto ref` parameters (the compiler should though, but only in the by-value-template-instantiation).
So this isn't cool at all ;) - please consider filing a bugreport about this.
February 04, 2017
On 02/04/2017 06:33 AM, Alex wrote:

> whether I'm
> doing something unsecure...

If you haven't already, you may want to read a recent thread as well:

  http://forum.dlang.org/post/jsksamnatzkshldnnrxq@forum.dlang.org

In addition to valuable information by others there, I tried to argue that explicit function overloads may be better than 'auto ref'. At least Jonathan M Davis did not agree and I agreed with him mostly because explicit function overloads don't scale like 'auto ref' does.

Ali

February 05, 2017
On Saturday, 4 February 2017 at 16:53:13 UTC, Ali Çehreli wrote:
> If you haven't already, you may want to read a recent thread as well:
>
> http://forum.dlang.org/post/jsksamnatzkshldnnrxq@forum.dlang.org

Thanks for the instructive link...
February 05, 2017
On Saturday, 4 February 2017 at 16:18:00 UTC, kinke wrote:
>
> It most likely only works because the dangling pointer points into yet untouched stack. Trying to öet a normal by-value parameter or local variable escape this way should produce an error, but apparently it's not done for `auto ref` parameters (the compiler should though, but only in the by-value-template-instantiation).
> So this isn't cool at all ;) - please consider filing a bugreport about this.

Ok, fine.
So the bug is that there is no error message about trying to get a pointer of an rvalue...