www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - returning delegates to nested function

reply BCS <BCS_member pathlink.com> writes:
Is this valid

int delegate(int) fn()
{
	int ret(int i)	// function doesn't use context pointer
	{
		return i+1;
	}	
	return &ret;	// returns delegate to _local_ nested function
}
Jan 09 2006
next sibling parent reply John Reimer <terminal.node gmail.com> writes:
BCS wrote:
 Is this valid
 
 int delegate(int) fn()
 {
     int ret(int i)    // function doesn't use context pointer
     {
         return i+1;
     }   
     return &ret;    // returns delegate to _local_ nested function
 }

I'm not so certain that nested functions are truly local (as in local variables) even though their style of declaration causes them to appear so. If you look at the assembler output, the declaration appears much like a global function, or else it used to, I think. I haven't checked again recently. The difference, of course, is that nested functions have access to their enclosing scopes local variables. As long as you don't access those, I imagine the above is possible. Does your dmd compiler allow this? -JJR
Jan 09 2006
parent reply BCS <BCS_member pathlink.com> writes:
John Reimer wrote:
 BCS wrote:
 
 Is this valid

 int delegate(int) fn()
 {
     int ret(int i)    // function doesn't use context pointer
     {
         return i+1;
     }       return &ret;    // returns delegate to _local_ nested 
 function
 }

I'm not so certain that nested functions are truly local (as in local variables) even though their style of declaration causes them to appear so. If you look at the assembler output, the declaration appears much like a global function, or else it used to, I think. I haven't checked again recently. The difference, of course, is that nested functions have access to their enclosing scopes local variables. As long as you don't access those, I imagine the above is possible. Does your dmd compiler allow this? -JJR

Yes, the function works fine with DMD. However I'm not shure that it is even legal to do this. As a sinde note, what is the best way to use a regular function where a delagate is needed? e.i. given: int fn(int delegate(int)); int use_me(int); needed: call fn w/ use_me.
Jan 09 2006
parent reply Chris Sauls <ibisbasenji gmail.com> writes:
BCS wrote:
 As a sinde note, what is the best way to use a regular function where a 
 delagate is needed?
 
 e.i.
 
 given:
 int fn(int delegate(int));
 int use_me(int);
 
 needed:
 call fn w/ use_me.

I'm not sure what the best way is, but this would probably work: # struct { int F_use_me (int x) { return use_me(x); } } # # fn(&F_use_me); -- Chris Sauls
Jan 09 2006
parent BCS <BCS_member pathlink.com> writes:
Chris Sauls wrote:
 BCS wrote:
 
 As a sinde note, what is the best way to use a regular function where 
 a delagate is needed?

 e.i.

 given:
 int fn(int delegate(int));
 int use_me(int);

 needed:
 call fn w/ use_me.

I'm not sure what the best way is, but this would probably work: # struct { int F_use_me (int x) { return use_me(x); } } # # fn(&F_use_me); -- Chris Sauls

Thought of that (actually I was think a class, but struct would do better) How about a asm hack (in sudo code) fn2dg( void* fnp, ...) { copy fnp to a register manipulate stack ptr/frame ptr to remove it from the stack jmp fnp } usage (per above example) fn(&(cast(void*)(&use_me).fn2dg)); Yuck!! :P but it would be fast maybe something like this should be put in the D (the cast of a function to a delegate could do this implicitly)
Jan 09 2006
prev sibling next sibling parent "Ben Hinkle" <bhinkle mathworks.com> writes:
"BCS" <BCS_member pathlink.com> wrote in message 
news:dpueko$6hc$1 digitaldaemon.com...
 Is this valid

 int delegate(int) fn()
 {
 int ret(int i) // function doesn't use context pointer
 {
 return i+1;
 } return &ret; // returns delegate to _local_ nested function
 }

If it doesn't use the context pointer it should be fine. I suppose the reason for making it local is for the name scoping, then? Note you can use an anonymous delegate int delegate(int) fn() { return delegate int(int i){return i+1;}; }
Jan 09 2006
prev sibling parent reply Sean Kelly <sean f4.ca> writes:
BCS wrote:
 Is this valid
 
 int delegate(int) fn()
 {
     int ret(int i)    // function doesn't use context pointer
     {
         return i+1;
     }   
     return &ret;    // returns delegate to _local_ nested function
 }

Technically, no. Why not use a function pointer instead? int function(int) fn() { static int ret( int i ) { return i + 1; } return &ret; }
Jan 09 2006
next sibling parent John Reimer <terminal.node gmail.com> writes:
Sean Kelly wrote:
 BCS wrote:
 Is this valid

 int delegate(int) fn()
 {
     int ret(int i)    // function doesn't use context pointer
     {
         return i+1;
     }       return &ret;    // returns delegate to _local_ nested 
 function
 }

Technically, no. Why not use a function pointer instead? int function(int) fn() { static int ret( int i ) { return i + 1; } return &ret; }

I totally missed the delegate/function pointer context here. -JJR
Jan 09 2006
prev sibling parent BCS <BCS_member pathlink.com> writes:
Sean Kelly wrote:
 BCS wrote:
 
 Is this valid

 int delegate(int) fn()
 {
     int ret(int i)    // function doesn't use context pointer
     {
         return i+1;
     }       return &ret;    // returns delegate to _local_ nested 
 function
 }

Technically, no. Why not use a function pointer instead? int function(int) fn() { static int ret( int i ) { return i + 1; } return &ret; }

I have a pre existing class that take a delegate in it's constructor and I need to use an instance of this class after the function I'm creating it in returns. A function would work except that the code is expecting a delegate
Jan 09 2006