www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Stack overflow / recursive expansion with alias this

reply "Namespace" <rswhite4 googlemail.com> writes:
I have this code:

import std.stdio;

struct NotNull(T : Object) {
private:
	T _value;

public:
	 disable
	this();
	
	// constructs with a runtime not null check (via assert())
	this(T value) {
		assert(value !is null);
		
		this._value = value;
	}
	
	 disable
	this(typeof(null)); // the null literal can be caught at compile 
time

	T _get() {
		return this._value;
	}
	
	const(T) _get() const {
		return this._value;
	}
	
	alias _get this;
}

NotNull!(T) assumeNotNull(T : Object)(T t) {
	return NotNull!(T)(t);
}

 property
NotNull!(T) makeNotNull(T : Object)() {
	T t = new T();
	
	return assumeNotNull(t);
}

class Foo {
	NotNull!(Foo) _convert() {
		return assumeNotNull(this);
	}
	
	alias _convert this;
}

void main() {

}

and get the error "recursive expansion". Can anybody explain that 
to me?

I reduce the Code to this simple example

class A {
private:
	B _b;

public:
	this(B b) {
		assert(b !is null);
		
		this._b = b;
	}
	
	B get() {
		return this._b;
	}
	
	alias get this;
}

class B {
public:
	A get() {
		return new B(this);
	}
	
	alias get this;
}

void main() {

}

And therefore i get the same error, as if i wrote "return 
NotNull!(Foo)(this);" instead of "return assumeNotNull(this);", 
in the "_convert" method of NotNull. The Output is "Stack 
overflow". I think that comes from recursive calls which fills 
the stack? Is that a bug?
Apr 23 2012
next sibling parent "Namespace" <rswhite4 googlemail.com> writes:
Hm, doesn't anybody know anything about it?
Apr 24 2012
prev sibling next sibling parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 04/23/2012 11:29 PM, Namespace wrote:
 I have this code:

      T _get() {
          return this._value;
      }

      const(T) _get() const {
          return this._value;
      }

You missed the 'immutable' and 'inout cases. Just use inout(T) _get() inout { return _value; } instead of the two declarations you have.
 ...
 And therefore i get the same error, as if i wrote "return
 NotNull!(Foo)(this);" instead of "return assumeNotNull(this);", in the
 "_convert" method of NotNull. The Output is "Stack overflow". I think
 that comes from recursive calls which fills the stack? Is that a bug?

Yes.
Apr 24 2012
parent Timon Gehr <timon.gehr gmx.ch> writes:
On 04/24/2012 07:09 PM, Namespace wrote:
 ...
 And therefore i get the same error, as if i wrote "return
 NotNull!(Foo)(this);" instead of "return assumeNotNull(this);", in the
 "_convert" method of NotNull. The Output is "Stack overflow". I think
 that comes from recursive calls which fills the stack? Is that a bug?

Yes.

I found nothing like that. Is the bug reported?

I remember reporting a similar issue, but that one seems to have been fixed. Feel free to create a new ticket.
Apr 24 2012
prev sibling next sibling parent "Namespace" <rswhite4 googlemail.com> writes:
 You missed the 'immutable' and 'inout cases.
 Just use inout(T) _get() inout { return _value; } instead of 
 the two declarations you have.

Oh, thanks a lot, i'm forgetting this often.
 ...
 And therefore i get the same error, as if i wrote "return
 NotNull!(Foo)(this);" instead of "return 
 assumeNotNull(this);", in the
 "_convert" method of NotNull. The Output is "Stack overflow". 
 I think
 that comes from recursive calls which fills the stack? Is that 
 a bug?

Yes.

Some ideas how i can implement this otherwise? And would the bug fix come with 2.060? With this functionality, the NotNull struct would be perfect.
Apr 24 2012
prev sibling next sibling parent "Namespace" <rswhite4 googlemail.com> writes:
 ...
 And therefore i get the same error, as if i wrote "return
 NotNull!(Foo)(this);" instead of "return 
 assumeNotNull(this);", in the
 "_convert" method of NotNull. The Output is "Stack overflow". 
 I think
 that comes from recursive calls which fills the stack? Is that 
 a bug?

Yes.

I found nothing like that. Is the bug reported?
Apr 24 2012
prev sibling next sibling parent "Namespace" <rswhite4 googlemail.com> writes:
On Tuesday, 24 April 2012 at 19:34:26 UTC, Timon Gehr wrote:
 On 04/24/2012 07:09 PM, Namespace wrote:
 ...
 And therefore i get the same error, as if i wrote "return
 NotNull!(Foo)(this);" instead of "return 
 assumeNotNull(this);", in the
 "_convert" method of NotNull. The Output is "Stack 
 overflow". I think
 that comes from recursive calls which fills the stack? Is 
 that a bug?

Yes.

I found nothing like that. Is the bug reported?

I remember reporting a similar issue, but that one seems to have been fixed. Feel free to create a new ticket.

That's what I do now. Thanks a lot for your help.
Apr 24 2012
prev sibling parent "Kenji Hara" <k.hara.pg gmail.com> writes:
On Tuesday, 24 April 2012 at 20:09:32 UTC, Namespace wrote:
 On Tuesday, 24 April 2012 at 19:34:26 UTC, Timon Gehr wrote:
 On 04/24/2012 07:09 PM, Namespace wrote:
 ...
 And therefore i get the same error, as if i wrote "return
 NotNull!(Foo)(this);" instead of "return 
 assumeNotNull(this);", in the
 "_convert" method of NotNull. The Output is "Stack 
 overflow". I think
 that comes from recursive calls which fills the stack? Is 
 that a bug?

Yes.

I found nothing like that. Is the bug reported?

I remember reporting a similar issue, but that one seems to have been fixed. Feel free to create a new ticket.

That's what I do now. Thanks a lot for your help.

Today I posted a pull to detect recursive alias this dependency. https://github.com/D-Programming-Language/dmd/pull/1028 Bye. Kenji Hara
Jun 27 2012