Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #108054 > unrolled thread

correct way to create dynamically function pointers

Started byHello World <acidlategamer@gmail.com>
First post2017-04-11 10:20 -0700
Last post2017-04-17 05:50 -0700
Articles 5 on this page of 25 — 12 participants

Back to article view | Back to comp.lang.c


Contents

  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]


#108082

FromRichard Heathfield <rjh@cpax.org.uk>
Date2017-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]


#108089

FromKeith Thompson <kst-u@mib.org>
Date2017-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]


#108076

FromJohn Bode <jfbode1029@gmail.com>
Date2017-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]


#108078

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2017-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]


#108198

FromTim Rentsch <txr@alumni.caltech.edu>
Date2017-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