Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #108054 > unrolled thread
| Started by | Hello World <acidlategamer@gmail.com> |
|---|---|
| First post | 2017-04-11 10:20 -0700 |
| Last post | 2017-04-17 05:50 -0700 |
| Articles | 5 on this page of 25 — 12 participants |
Back to article view | Back to comp.lang.c
correct way to create dynamically function pointers Hello World <acidlategamer@gmail.com> - 2017-04-11 10:20 -0700
Re: correct way to create dynamically function pointers scott@slp53.sl.home (Scott Lurndal) - 2017-04-11 17:34 +0000
Re: correct way to create dynamically function pointers Hello World <acidlategamer@gmail.com> - 2017-04-11 10:42 -0700
Re: correct way to create dynamically function pointers scott@slp53.sl.home (Scott Lurndal) - 2017-04-11 17:48 +0000
Re: correct way to create dynamically function pointers Hello World <acidlategamer@gmail.com> - 2017-04-11 10:55 -0700
Re: correct way to create dynamically function pointers Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-04-11 19:06 +0100
Re: correct way to create dynamically function pointers "James R. Kuyper" <jameskuyper@verizon.net> - 2017-04-11 14:23 -0400
Re: correct way to create dynamically function pointers Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-04-11 19:05 +0100
Re: correct way to create dynamically function pointers "James R. Kuyper" <jameskuyper@verizon.net> - 2017-04-11 14:11 -0400
Re: correct way to create dynamically function pointers Richard Heathfield <rjh@cpax.org.uk> - 2017-04-12 08:27 +0100
Re: correct way to create dynamically function pointers "James R. Kuyper" <jameskuyper@verizon.net> - 2017-04-12 13:31 -0400
Re: correct way to create dynamically function pointers Richard Heathfield <rjh@cpax.org.uk> - 2017-04-12 23:05 +0100
Re: correct way to create dynamically function pointers Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-04-11 19:03 +0100
Re: correct way to create dynamically function pointers "James R. Kuyper" <jameskuyper@verizon.net> - 2017-04-11 14:05 -0400
Re: correct way to create dynamically function pointers Jorgen Grahn <grahn+nntp@snipabacken.se> - 2017-04-15 10:19 +0000
Re: correct way to create dynamically function pointers asetofsymbols@gmail.com - 2017-04-15 05:09 -0700
Re: correct way to create dynamically function pointers Barry Schwarz <schwarzb@dqel.com> - 2017-04-11 15:13 -0700
Re: correct way to create dynamically function pointers Richard Heathfield <rjh@cpax.org.uk> - 2017-04-12 08:28 +0100
Re: correct way to create dynamically function pointers Richard Heathfield <rjh@cpax.org.uk> - 2017-04-12 08:19 +0100
Re: correct way to create dynamically function pointers Spiros Bousbouras <spibou@gmail.com> - 2017-04-12 21:17 +0000
Re: correct way to create dynamically function pointers Richard Heathfield <rjh@cpax.org.uk> - 2017-04-12 23:11 +0100
Re: correct way to create dynamically function pointers Keith Thompson <kst-u@mib.org> - 2017-04-12 16:36 -0700
Re: correct way to create dynamically function pointers John Bode <jfbode1029@gmail.com> - 2017-04-12 10:04 -0700
Re: correct way to create dynamically function pointers Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-04-12 19:28 +0100
Re: correct way to create dynamically function pointers Tim Rentsch <txr@alumni.caltech.edu> - 2017-04-17 05:50 -0700
Page 2 of 2 — ← Prev page 1 [2]
| From | Richard Heathfield <rjh@cpax.org.uk> |
|---|---|
| Date | 2017-04-12 23:11 +0100 |
| Message-ID | <ocm8ga$m8c$1@dont-email.me> |
| In reply to | #108079 |
On 12/04/17 22:17, Spiros Bousbouras wrote:
> On Wed, 12 Apr 2017 08:19:00 +0100
> Richard Heathfield <rjh@cpax.org.uk> wrote:
>> Here is the code with the typedef in place:
>>
>> #include <stdio.h>
>> #include <stdlib.h>
>>
>> int sum(int a, int b);
>> int subt(int a, int b);
>> int mul(int a, int b);
>> int dive(int a, int b);
>>
>> typedef int ft_arithmetic(int, int);
>>
>> int sum(int a, int b) { return a+b; }
>> int subt(int a, int b) { return a-b; }
>> int mul(int a, int b) { return a*b; }
>> int dive(int a, int b) { return a/b; }
>>
>> int main(void)
>> {
>> ft_arithmetic **p = malloc(4 * sizeof *p);
>> if(p != NULL)
>> {
>> p[0] = sum;
>> p[1] = subt;
>> p[2] = mul;
>> p[3] = dive;
>> printf("p[0](4, 6) = %d\n",(*p[0])(4, 6));
>
> Or more simply
> printf("p[0](4, 6) = %d\n",p[0](4, 6));
I disagree that it's necessarily simpler. It's /shorter/, yes.
But (*p[0]) tells us something useful - i.e. it reminds us that p[0] is
a pointer, not a function. Now, okay, I realise that p[0] can't be the
name of a function! Nevertheless, in the general case I prefer to use
parentheses (*p)() rather than p() when a function pointer is being
used, as a little reminder that there's no point in going looking for a
function p.
(And yes, just to reiterate, I do realise that nobody in their right
mind is going to try to find a function by the name p[0]. So I find your
point to be more persuasive in this case than I would in the general case.)
>
> which actually agrees with the message printed and that's already true
> in the OP's code. Same for the other 3 calls.
>
>> printf("p[1](4, 6) = %d\n",(*p[1])(4, 6));
>> printf("p[2](4, 6) = %d\n",(*p[2])(4, 6));
>> printf("p[3](4, 6) = %d\n",(*p[3])(4, 6));
>> free(p);
>> }
>> return 0;
>> }
While we're at it, why not:
for(i = 0; i < 4; i++)
{
printf("p[%d](4, 6) = %d\n", i, (*p[i])(4, 6));
}
--
Richard Heathfield
Email: rjh at cpax dot org dot uk
"Usenet is a strange place" - dmr 29 July 1999
Sig line 4 vacant - apply within
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2017-04-12 16:36 -0700 |
| Message-ID | <lny3v5urju.fsf@kst-u.example.com> |
| In reply to | #108082 |
Richard Heathfield <rjh@cpax.org.uk> writes:
> On 12/04/17 22:17, Spiros Bousbouras wrote:
>> On Wed, 12 Apr 2017 08:19:00 +0100
>> Richard Heathfield <rjh@cpax.org.uk> wrote:
[...]
>>> printf("p[0](4, 6) = %d\n",(*p[0])(4, 6));
>>
>> Or more simply
>> printf("p[0](4, 6) = %d\n",p[0](4, 6));
>
> I disagree that it's necessarily simpler. It's /shorter/, yes.
In any case, it would be nice for the expression in the format string to
match the function call.
> But (*p[0]) tells us something useful - i.e. it reminds us that p[0] is
> a pointer, not a function. Now, okay, I realise that p[0] can't be the
> name of a function! Nevertheless, in the general case I prefer to use
> parentheses (*p)() rather than p() when a function pointer is being
> used, as a little reminder that there's no point in going looking for a
> function p.
I agree that it's a useful reminder. On the other hand, the prefix to a
function call is *always* a expression of pointer-to-function type, so
if one were being deliberately perverse, one could cause great confusion
by inverting the convention:
void func(void) {
/* ... */
}
void (*funcptr)(void) = func;
int main(void) {
(*func)();
funcptr();
}
Not that I'd ever doing such a thing, of course.
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
| From | John Bode <jfbode1029@gmail.com> |
|---|---|
| Date | 2017-04-12 10:04 -0700 |
| Message-ID | <5fa241bc-1f87-4e9b-b457-9f3af24e093a@googlegroups.com> |
| In reply to | #108054 |
On Tuesday, April 11, 2017 at 12:20:13 PM UTC-5, Hello World wrote:
> Hi all,
>
> I am learning C but I don't understand certain topics with much clarity.
> I came to know that normally it is better to use dynamic memory allocation, so I tried to make a c program that will dynamically allocate memory for function pointers. I wrote this
>
> #include <stdio.h>
> #include <stdlib.h>
>
> int sum(int a, int b);
> int subt(int a, int b);
> int mul(int a, int b);
> int dive(int a, int b);
>
> int (*p)(int a, int b);
>
>
>
> int sum(int a, int b)
> {
> return a+b;
> }
>
> int subtract(int a, int b)
> {
> return a-b;
> }
>
> int mul(int a, int b)
> {
> return a*b;
> }
>
> int dive(int a, int b)
> {
> return a/b;
> }
>
> int main(void)
> {
> p = malloc(sizeof(p)*4);
> p[0] = sum;
> p[1] = subt;
> p[2] = mul;
> p[3] = dive;
> printf("p[0](4, 6) = %d\n",(*p[0])(4, 6));
> printf("p[1](4, 6) = %d\n",(*p[1])(4, 6));
> printf("p[2](4, 6) = %d\n",(*p[2])(4, 6));
> printf("p[3](4, 6) = %d\n",(*p[3])(4, 6));
> free(p);
> return 0;
> }
>
> }
>
> However I get an error
>
> warning: ISO C forbids assignment between function pointer and ‘void *’ [-Wpedantic]
> p = malloc(sizeof(p)*4);
> ^
>
> It looks like that function pointer is a different kind of pointer.
> What am I missing?
Let's start from the beginning. If you want to dynamically allocate an
N-element array of any type T, you'd write:
T *p = malloc( N * sizeof *p );
or
T *p = NULL;
...
p = malloc( N * sizeof *p );
After this, each p[i] contains a value of type T.
Now, let's replace T with a pointer type, P * - you want to allocate an
N-element array of *pointers* to P:
P **p = malloc( N * sizeof *p );
or
P **p = NULL;
...
p = malloc( N * sizeof *p );
After this, each p[i] contains a value of type P *, and the expression
*p[i] has type P. Basically, you've added an extra level of indirection
on p.
Now, replace P * with the function pointer type int (*)(int, int):
int (**p)(int, int) = malloc( N * sizeof *p );
or
int (**p)(int, int) = NULL;
...
p = malloc( N * sizeof *p );
After this, each p[i] contains a value of type int (*)(int, int).
So, basically, you were just missing one level of indirection on your
declaration of p.
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2017-04-12 19:28 +0100 |
| Message-ID | <8737ddzdjd.fsf@bsb.me.uk> |
| In reply to | #108076 |
John Bode <jfbode1029@gmail.com> writes: <snip> > Let's start from the beginning. If you want to dynamically allocate an > N-element array of any type T, you'd write: > > T *p = malloc( N * sizeof *p ); > > or > > T *p = NULL; > ... > p = malloc( N * sizeof *p ); > > After this, each p[i] contains a value of type T. s/contains/can contain/ After the malloc call each p[i] has indeterminate value. That value can't be used in any way. All you can do is use p[i] as somewhere to put a value of type T > Now, let's replace T with a pointer type, P * - you want to allocate an > N-element array of *pointers* to P: > > P **p = malloc( N * sizeof *p ); > > or > > P **p = NULL; > ... > p = malloc( N * sizeof *p ); > > After this, each p[i] contains a value of type P *, Same here. True only once you've put something determinate in p[i]. <snip> -- Ben.
[toc] | [prev] | [next] | [standalone]
| From | Tim Rentsch <txr@alumni.caltech.edu> |
|---|---|
| Date | 2017-04-17 05:50 -0700 |
| Message-ID | <kfnfuh76vwj.fsf@x-alumni2.alumni.caltech.edu> |
| In reply to | #108076 |
John Bode <jfbode1029@gmail.com> writes:
> On Tuesday, April 11, 2017 at 12:20:13 PM UTC-5, Hello World wrote:
>> [...] I tried to make a c program that will dynamically
>> allocate memory for function pointers. I wrote this
>>
>> [...]
>>
>> int (*p)(int a, int b);
>>
>> [...]
>>
>> int main(void)
>> {
>> p = malloc(sizeof(p)*4);
>> [...]
>> }
>>
>> However I get an error [...]
>>
>> It looks like that function pointer is a different kind of pointer.
>> What am I missing?
>
> Let's start from the beginning. If you want to dynamically allocate an
> N-element array of any type T, you'd write:
>
> T *p = malloc( N * sizeof *p );
>
> or
>
> T *p = NULL;
> ...
> p = malloc( N * sizeof *p );
>
> After this, each p[i] contains a value of type T.
>
> Now, let's replace T with a pointer type, P * [..elaborate on this..]
Excellent explanation. I thought this reply the best of the ones
I saw.
> So, basically, you were just missing one level of indirection on your
> declaration of p.
One suggestion: here it would have been good to point out the
OP's code that incorrectly follows the malloc() pattern
[from OP] p = malloc(sizeof(p)*4);
and give again the correction for that, especially since if this
line had been written
p = malloc(sizeof(*p)*4);
the resulting error message might have been enough for OP
to fix the problem without further help.
[toc] | [prev] | [standalone]
Page 2 of 2 — ← Prev page 1 [2]
Back to top | Article view | comp.lang.c
csiph-web