D - Function pointers
- "Ben Cohen" <bc skygate.co.uk> Oct 16 2001
- "Walter" <walter digitalmars.com> Oct 16 2001
- Axel Kittenberger <axel dtone.org> Oct 16 2001
- "Ben Cohen" <bc skygate.co.uk> Oct 17 2001
- "Jeffrey Drake" <jpt.d home.com> Oct 19 2001
- Axel Kittenberger <axel dtone.org> Oct 20 2001
- "Sean L. Palmer" <spalmer iname.com> Oct 23 2001
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
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
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
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; instead of: 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
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
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
statements above. E.g.: /* Declare a variable to which you assign a function taking no
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.
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
Jeffrey Drake wrote: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.
Can you paste an example maybe?
Oct 20 2001
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









Axel Kittenberger <axel dtone.org> 