Thread overview
function pointer vs. delegate
Nov 30, 2005
James Dunne
Nov 30, 2005
David Medlock
Nov 30, 2005
Derek Parnell
Dec 01, 2005
James Dunne
Dec 01, 2005
Russ Lewis
Dec 01, 2005
Don Clugston
November 30, 2005
Okay, it's been bugging me long enough; I'm just going to swallow my pride and ask.

What is the difference between a function pointer and a delegate?

I use function pointers all the time from C and I really enjoy using them.  But now C#, D, and other guys come out with delegates, which I just assumed were function pointers but renamed.  It seems they are slightly more than this.

Can someone clearly lay out the side-by-side differences of these two seemingly similar concepts?
November 30, 2005
James Dunne wrote:
> Okay, it's been bugging me long enough; I'm just going to swallow my pride and ask.
> 
> What is the difference between a function pointer and a delegate?
> 
> I use function pointers all the time from C and I really enjoy using them.  But now C#, D, and other guys come out with delegates, which I just assumed were function pointers but renamed.  It seems they are slightly more than this.
> 
> Can someone clearly lay out the side-by-side differences of these two seemingly similar concepts?

Function pointers can only access the variables passed to them and declared within(also globals).  A delegate can access any variables visible to the enclosing scope.

Basically this means a delegate is analagous to a member function whereas a function pointer is just like the C version.

Here is an example with an inner function:

void foo( int a )
{
  void bar() { writefln( a ); }
  call( &bar );
}

void call( void delegate() dg  ) { dg(); }
int main( char[][] args ) {
  foo( 100 );
}


Notice how the bar function has access to the local variable a, even though it was not passed to the function call() ?

There is a hidden reference within the delegate to the stack frame inside the call to foo().  Obviously the delegate '&bar' will not be valid once your code exits the foo() function.

Hope this helps a bit.
-DavidM
November 30, 2005
On Wed, 30 Nov 2005 12:54:09 -0600, James Dunne wrote:

> Okay, it's been bugging me long enough; I'm just going to swallow my pride and ask.
> 
> What is the difference between a function pointer and a delegate?
> 
> I use function pointers all the time from C and I really enjoy using them.  But now C#, D, and other guys come out with delegates, which I just assumed were function pointers but renamed.  It seems they are slightly more than this.
> 
> Can someone clearly lay out the side-by-side differences of these two seemingly similar concepts?

The code inside a delegated function can access variables that are visible at the same scope level as that function.

In other words, use delegates if the function is a nested function or inside a class/struct. That way, the function can access variables local to the enclosing function/class/struct. Functions accessed via a function pointer are not passed the 'hidden' reference pointer to the enclosing scope, i.e the stack pointer or 'this'.

===== example =================
import std.stdio;
import std.conv;
void main(char[][] pArgs)
{
    int hostfunc(int foo)
    {
        int nestA(int qwerty)
        {
            return (-foo + qwerty);
        }

        int nestB(int qwerty)
        {
            return (foo - qwerty);
        }
        int delegate(int q) n;

        n = (foo < 0 ? &nestA : &nestB);

        return n(toInt(pArgs[1]));
    }

    for (int x = -6; x < 7; x+=3)
    {
        writefln("%d %d", x, hostfunc(x));
    }
}
=====================

f:\temp>build test
Path and Version : D:\UTIL\build.exe v2.9(1197)
  built on Wed Aug 10 11:03:42 2005
f:\dmd\bin\..\..\dm\bin\link.exe
test,test.exe,,user32+kernel32,test.def/noi;

f:\temp>test 10
-6 16
-3 13
0 -10
3 -7
6 -4

f:\temp>test 100
-6 106
-3 103
0 -100
3 -97
6 -94

-- 
Derek Parnell
Melbourne, Australia
1/12/2005 6:26:10 AM
December 01, 2005
Derek Parnell wrote:
> On Wed, 30 Nov 2005 12:54:09 -0600, James Dunne wrote:
> 
> 
>>Okay, it's been bugging me long enough; I'm just going to swallow my pride and ask.
>>
>>What is the difference between a function pointer and a delegate?
>>
>>I use function pointers all the time from C and I really enjoy using them.  But now C#, D, and other guys come out with delegates, which I just assumed were function pointers but renamed.  It seems they are slightly more than this.
>>
>>Can someone clearly lay out the side-by-side differences of these two seemingly similar concepts?
> 
> 
> The code inside a delegated function can access variables that are visible
> at the same scope level as that function.
> 
> In other words, use delegates if the function is a nested function or
> inside a class/struct. That way, the function can access variables local to
> the enclosing function/class/struct. Functions accessed via a function
> pointer are not passed the 'hidden' reference pointer to the enclosing
> scope, i.e the stack pointer or 'this'.
> 
> ===== example =================
> import std.stdio;
> import std.conv;
> void main(char[][] pArgs)
> {
>     int hostfunc(int foo)
>     {
>         int nestA(int qwerty)
>         {
>             return (-foo + qwerty);
>         }
>                 int nestB(int qwerty)
>         {
>             return (foo - qwerty);
>         }
>         int delegate(int q) n;
>                 n = (foo < 0 ? &nestA : &nestB);
>                 return n(toInt(pArgs[1]));
>     }
>         for (int x = -6; x < 7; x+=3)
>     {
>         writefln("%d %d", x, hostfunc(x));
>     }
> }
> =====================
> 
> f:\temp>build test
> Path and Version : D:\UTIL\build.exe v2.9(1197)
>   built on Wed Aug 10 11:03:42 2005
> f:\dmd\bin\..\..\dm\bin\link.exe
> test,test.exe,,user32+kernel32,test.def/noi;
> 
> f:\temp>test 10
> -6 16
> -3 13
> 0 -10
> 3 -7
> 6 -4
> 
> f:\temp>test 100
> -6 106
> -3 103
> 0 -100
> 3 -97
> 6 -94
> 

To both Derek and David:

Thanks a lot.  I figured it was some minute detail like that.  Of course, you can simulate the behavior of a delegate using a function pointer that takes a 'this' pointer as the first parameter.  I've done this in C++ before; but that was way back before I discovered the member function pointer bass-ackwards syntax. =P

I seem to recall a recent post about someone saying that D doesn't have member function pointers... That seems to make more sense now, since a delegate can only access variables local to the CALLER's scope, not the scope in which it was defined.  Is this correct?
December 01, 2005
James Dunne wrote:

> Thanks a lot.  I figured it was some minute detail like that.  Of course, you can simulate the behavior of a delegate using a function pointer that takes a 'this' pointer as the first parameter.  I've done this in C++ before; but that was way back before I discovered the member function pointer bass-ackwards syntax. =P
> 
> I seem to recall a recent post about someone saying that D doesn't have member function pointers... That seems to make more sense now, since a delegate can only access variables local to the CALLER's scope, not the scope in which it was defined.  Is this correct?

No, the variables it can access are defined at the time of CREATION, not  call.

I prefer to think of delegates the way that you described them: they are like C function pointers, but with an implicit "this".  "this" can point to anything, but it is the creator which decides what it points to.



You need to remember that there are two types of delegates:

You can build a member function *delegate* by the following:
  class Foo {
    char bar(int) {...}
  }
  Foo f = new Foo;
  bar delegate(int) myDelegate = f.bar;
The delegate has an implicit pointer to 'f' (actually a pointer to the thing that 'f' is a pointer to), and when you run it, it is exactly the same as running f.bar(...) - it can access any of the variables that bar() can.

You can build a delegate literal as well; this has access to any variables that your scope had access to:
  int baz() {
    int i,j,k;
    void delegate() callback = delegate void() { ... };

    ...
    callback();
    ...
  }
Think of a delegate literal as a C function pointer where the implicit 'this' is pointing to the stack frame.  Delegate literals are often used in D for callbacks; you might pass a delegate literal to some library function, and that library function calls you one or more times to return data to you.

Remember that delegate literals become undefined the moment that you leave the stack frame where they were created.  So they cannot ever be returned from a function.  It's ok, however, to return a delegate which points to a member function.  COOL TRICK: Create an object (or struct on the heap), and take a member function delegate to it...then forget the pointer to the object.  The implicit 'this' pointer inside the delegate will keep the object alive (prevent garbage collection of it) as long as you store the delegate.



I never totally understood C++ member function pointers, but I think that they are a little different than member delegates.  With member delegates, what you have is a function pointer to a very specific object; you cannot store a member delegate and expect to be able to execute it on different instances of your class.  I think that C++ member function pointers allow for that.

In D, you can get most of the same functionality using interfaces.
December 01, 2005
Russ Lewis wrote:
> James Dunne wrote:
> 
>> Thanks a lot.  I figured it was some minute detail like that.  Of course, you can simulate the behavior of a delegate using a function pointer that takes a 'this' pointer as the first parameter.  I've done this in C++ before; but that was way back before I discovered the member function pointer bass-ackwards syntax. =P
>>
>> I seem to recall a recent post about someone saying that D doesn't have member function pointers... That seems to make more sense now, since a delegate can only access variables local to the CALLER's scope, not the scope in which it was defined.  Is this correct?
> 
> 
> No, the variables it can access are defined at the time of CREATION, not  call.
> 
> I prefer to think of delegates the way that you described them: they are like C function pointers, but with an implicit "this".  "this" can point to anything, but it is the creator which decides what it points to.
> 
> 
> 
> You need to remember that there are two types of delegates:
> 
> You can build a member function *delegate* by the following:
>   class Foo {
>     char bar(int) {...}
>   }
>   Foo f = new Foo;
>   bar delegate(int) myDelegate = f.bar;
> The delegate has an implicit pointer to 'f' (actually a pointer to the thing that 'f' is a pointer to), and when you run it, it is exactly the same as running f.bar(...) - it can access any of the variables that bar() can.
> 
> You can build a delegate literal as well; this has access to any variables that your scope had access to:
>   int baz() {
>     int i,j,k;
>     void delegate() callback = delegate void() { ... };
> 
>     ...
>     callback();
>     ...
>   }
> Think of a delegate literal as a C function pointer where the implicit 'this' is pointing to the stack frame.  Delegate literals are often used in D for callbacks; you might pass a delegate literal to some library function, and that library function calls you one or more times to return data to you.
> 
> Remember that delegate literals become undefined the moment that you leave the stack frame where they were created.  So they cannot ever be returned from a function.  It's ok, however, to return a delegate which points to a member function.  COOL TRICK: Create an object (or struct on the heap), and take a member function delegate to it...then forget the pointer to the object.  The implicit 'this' pointer inside the delegate will keep the object alive (prevent garbage collection of it) as long as you store the delegate.
> 
> 
> 
> I never totally understood C++ member function pointers, but I think that they are a little different than member delegates.  With member delegates, what you have is a function pointer to a very specific object; you cannot store a member delegate and expect to be able to execute it on different instances of your class.  I think that C++ member function pointers allow for that.

Nobody fully understands member function pointers. My article:

http://www.codeproject.com/cpp/fastdelegate.asp

explains just how horrid the C++ situation with member function pointers is. Member function pointers live in a shadowy world between built-in types and user-defined types; they masquerade as pointers, but they're actually undocumented, vendor-specific structs. It's a complete debacle.

> In D, you can get most of the same functionality using interfaces.