## D - Function pointers

• Ben Cohen (38/38) Oct 16 2001 In C, you can create a variable which points to a function:
• Walter (5/43) Oct 16 2001 You bring up an interesting point. I never liked the implictness in C
• Sean L. Palmer (8/17) Oct 23 2001 I like this form. Consistent with the rest of the typespec system. Whe...
"Ben Cohen" <bc skygate.co.uk> writes:
```In C, you can create a variable which points to a function:

int (*my_func)();

I can then assign the address of a function with the same prototype to
this variable:

int a_func() { ... }

/* These are equivalent */
my_func = &a_func;
my_func = a_func;

And then I can call my_func as if calling a_func; the following are
equivalent:

int d = a_func();
d = my_func();
d = (*my_func)();

I find the definition of my_func, and the equivalence of my_func with
*my_func and a_func with &a_func a bit confusing.

I note that in D, since you use import and forward declarations you are no
longer allowed to declare function prototypes.  (This is stated in the
spec.)

As a result, you have "freed" that syntax and could use it to simplify the
statements above.

E.g.:

/* Declare a variable to which you assign a function taking no parameters
and returning int. */
int my_func();

int a_func() { ... }
my_func = a_func;

/* These are equivalent: */
int d = a_func();
d = my_func();

This simplifies things and no pointers are now explicitly involved; I
think the pointer above is a bit artificial anyway -- if it wasn't for
prototypes, I would hope that C would have used this syntax anyway. (This
is similar in spirit to replacing -> with . in structs.)

You could even go further and make the variable definition like this:

int() my_func;

This has the advantage (over "int my_func();") of not clashing with
existing C syntax, being easier to understand and being consistent with
array definitions.
```
Oct 16 2001
"Walter" <walter digitalmars.com> writes:
```You bring up an interesting point. I never liked the implictness in C
regarding function pointers, I was thinking of doing away with it by
requiring you to use & when taking the address of a function. -Walter

"Ben Cohen" <bc skygate.co.uk> wrote in message
news:9qhm2p\$2b4t\$1 digitaldaemon.com...
In C, you can create a variable which points to a function:

int (*my_func)();

I can then assign the address of a function with the same prototype to
this variable:

int a_func() { ... }

/* These are equivalent */
my_func = &a_func;
my_func = a_func;

And then I can call my_func as if calling a_func; the following are
equivalent:

int d = a_func();
d = my_func();
d = (*my_func)();

I find the definition of my_func, and the equivalence of my_func with
*my_func and a_func with &a_func a bit confusing.

I note that in D, since you use import and forward declarations you are no
longer allowed to declare function prototypes.  (This is stated in the
spec.)

As a result, you have "freed" that syntax and could use it to simplify the
statements above.

E.g.:

/* Declare a variable to which you assign a function taking no parameters
and returning int. */
int my_func();

int a_func() { ... }
my_func = a_func;

/* These are equivalent: */
int d = a_func();
d = my_func();

This simplifies things and no pointers are now explicitly involved; I
think the pointer above is a bit artificial anyway -- if it wasn't for
prototypes, I would hope that C would have used this syntax anyway. (This
is similar in spirit to replacing -> with . in structs.)

You could even go further and make the variable definition like this:

int() my_func;

This has the advantage (over "int my_func();") of not clashing with
existing C syntax, being easier to understand and being consistent with
array definitions.

```
Oct 16 2001
Axel Kittenberger <axel dtone.org> writes:
``` You bring up an interesting point. I never liked the implictness in C
regarding function pointers, I was thinking of doing away with it by
requiring you to use & when taking the address of a function. -Walter

I took the '^' operator, removed it's xor meaning. (xor is instead the
binary '~') and assigned it to be the function pointer operator. Get the
address from a function you need the ^ operator, assign the value of a
function pointer, ^ operator, call the function it is pointing at, no ^.

Btw, I also changed the meaning of the '&' operator, it's no longer 100%ly
address-of, but means just means "reference-of". There are slight
differences in some functions, the reference of a reference is again just
the reference.

int cork(int &i) # gets i by reference...
{
if (i > 0) {
i--;
cork(&i);   # tell the compiler and reader to be aware that the
# of i can be changed after the call. (context free reading)
}
}

- Axel
--
|D) http://www.dtone.org
```
Oct 16 2001
"Ben Cohen" <bc skygate.co.uk> writes:
```In article <9qi29e\$2i0v\$1 digitaldaemon.com>, "Walter"
<walter digitalmars.com> wrote:

You bring up an interesting point. I never liked the implictness in C
regarding function pointers, I was thinking of doing away with it by
requiring you to use & when taking the address of a function. -Walter

Hmm...

Using & has the advantage that you have to explicitly do it:

my_func = &a_func;

Thus you can't accidentally call a_func without the brackets, giving a
null statement:

my_func;
my_var = my_func;

my_func();
my_var = my_func();

However, this should in any case be caught by D (according to the spec) if
you do this as a single statement, and if you try to use its value then
there will be a type error; so I don't think this will be a problem.

I prefer not to use & since it brings in pointer notation where it could
be avoided; also, you don't _have_ to use it in C.  However, if you can
call my_func() in the same way as a_func(), rather than having to call
(*my_func)(), then this suggests to me that they are of the same type and
should be assigned without using &.

The bit I think is more confusing is having to use * in the C variable
type defintion when you don't really mean it.  (You could mean it if you
were making an array of pointers to functions.  But then in C you would
have to use **.  You still have to add one more * than I think is
necessary.  It is this which creates all the other confusion in this
matter.)

Functions should certainly behave more predictably:  this program works in
gcc (I don't know whether it is valid standard C), with all functions
returning the same value:

int test() {  return 45; }

int (*test_p)() = test;  /* or &test */
int (**test_pp)() = &test_p;

main() {
printf("%d\n", test());
printf("%d\n", (***test)());
printf("%d\n", test_p());
printf("%d\n", (*test_p)());
printf("%d\n", (**test_p)());
printf("%d\n", (*test_pp)());
printf("%d\n", (**test_pp)());
printf("%d\n", (***test_pp)());
printf("%d\n", (****test_pp)());
}

In other words, you can add as many ********* as you like in front of
function calls without changing the effect.  This is silly and should
probably be an error.  The one thing that makes sense here is that test_pp
is a pointer to a function, so you can't call "test_pp()" and have to
dereference it first.
```
Oct 17 2001
"Jeffrey Drake" <jpt.d home.com> writes:
```How about a delegate?

It basically is a prototype of a function that has delegate (keyword) in
front of it. It is C#'s way of making function pointers and i like it a lot.

Regards,
jptd

"Walter" <walter digitalmars.com> wrote in message
news:9qi29e\$2i0v\$1 digitaldaemon.com...
You bring up an interesting point. I never liked the implictness in C
regarding function pointers, I was thinking of doing away with it by
requiring you to use & when taking the address of a function. -Walter

"Ben Cohen" <bc skygate.co.uk> wrote in message
news:9qhm2p\$2b4t\$1 digitaldaemon.com...
In C, you can create a variable which points to a function:

int (*my_func)();

I can then assign the address of a function with the same prototype to
this variable:

int a_func() { ... }

/* These are equivalent */
my_func = &a_func;
my_func = a_func;

And then I can call my_func as if calling a_func; the following are
equivalent:

int d = a_func();
d = my_func();
d = (*my_func)();

I find the definition of my_func, and the equivalence of my_func with
*my_func and a_func with &a_func a bit confusing.

I note that in D, since you use import and forward declarations you are

no
longer allowed to declare function prototypes.  (This is stated in the
spec.)

As a result, you have "freed" that syntax and could use it to simplify

the
statements above.

E.g.:

/* Declare a variable to which you assign a function taking no

parameters
and returning int. */
int my_func();

int a_func() { ... }
my_func = a_func;

/* These are equivalent: */
int d = a_func();
d = my_func();

This simplifies things and no pointers are now explicitly involved; I
think the pointer above is a bit artificial anyway -- if it wasn't for
prototypes, I would hope that C would have used this syntax anyway.

(This
is similar in spirit to replacing -> with . in structs.)

You could even go further and make the variable definition like this:

int() my_func;

This has the advantage (over "int my_func();") of not clashing with
existing C syntax, being easier to understand and being consistent with
array definitions.

```
Oct 19 2001
Axel Kittenberger <axel dtone.org> writes:
```Jeffrey Drake wrote:

It basically is a prototype of a function that has delegate (keyword) in
front of it. It is C#'s way of making function pointers and i like it a
lot.

Can you paste an example maybe?
```
Oct 20 2001
"Sean L. Palmer" <spalmer iname.com> writes:
``` This simplifies things and no pointers are now explicitly involved; I
think the pointer above is a bit artificial anyway -- if it wasn't for
prototypes, I would hope that C would have used this syntax anyway. (This
is similar in spirit to replacing -> with . in structs.)

You could even go further and make the variable definition like this:

int() my_func;

This has the advantage (over "int my_func();") of not clashing with
existing C syntax, being easier to understand and being consistent with
array definitions.

I like this form.  Consistent with the rest of the typespec system.  When
dealing with a variable that holds function type, of *course* it's a
pointer-to-function, it's certainly not going to go around copying the
machine-code for the function around at runtime.  So the pointer part is
unnecessary with function pointers and can be implicit.  Still different
enough from a normal function declaration that the parser won't have trouble
with it.

Sean
```
Oct 23 2001