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 20 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 1 of 2  [1] 2  Next page →


#108054 — correct way to create dynamically function pointers

FromHello World <acidlategamer@gmail.com>
Date2017-04-11 10:20 -0700
Subjectcorrect way to create dynamically function pointers
Message-ID<b6cbce81-b326-4c26-9079-23e083b2de56@googlegroups.com>
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?

[toc] | [next] | [standalone]


#108055

Fromscott@slp53.sl.home (Scott Lurndal)
Date2017-04-11 17:34 +0000
Message-ID<vs8HA.4$eU.3@fx14.iad>
In reply to#108054
Hello World <acidlategamer@gmail.com> writes:
>Hi all,=20
>
>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 f=
>unction pointers. I wrote this
>

>However I get an error
>
>warning: ISO C forbids assignment between function pointer and =E2=80=98voi=
>d *=E2=80=99 [-Wpedantic]
>  p =3D malloc(sizeof(p)*4);
>    ^
>

ISO C forbids that because on some architectures, a function pointer
may require more bits than a void pointer contains.[*]


>What am I missing?

a cast.  (puts on flameproof suit).

[*] On one segmented architecture I used to use, a function pointer required 10-bytes,
    whereas a data pointer was 4-bytes.

[toc] | [prev] | [next] | [standalone]


#108056

FromHello World <acidlategamer@gmail.com>
Date2017-04-11 10:42 -0700
Message-ID<8dfc1237-0a3b-4cc5-bac9-403a0ccff2a7@googlegroups.com>
In reply to#108055
On Tuesday, April 11, 2017 at 11:04:27 PM UTC+5:30, Scott Lurndal wrote:
> Hello World <acidlategamer@gmail.com> writes:
> >Hi all,=20
> >
> >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 f=
> >unction pointers. I wrote this
> >
> 
> >However I get an error
> >
> >warning: ISO C forbids assignment between function pointer and =E2=80=98voi=
> >d *=E2=80=99 [-Wpedantic]
> >  p =3D malloc(sizeof(p)*4);
> >    ^
> >
> 
> ISO C forbids that because on some architectures, a function pointer
> may require more bits than a void pointer contains.[*]
> 
> 
> >What am I missing?
> 
> a cast.  (puts on flameproof suit).
> 
> [*] On one segmented architecture I used to use, a function pointer required 10-bytes,
>     whereas a data pointer was 4-bytes.

As far as I know pointer variable have same size in an architecure.

[toc] | [prev] | [next] | [standalone]


#108057

Fromscott@slp53.sl.home (Scott Lurndal)
Date2017-04-11 17:48 +0000
Message-ID<4G8HA.150$cU1.53@fx27.iad>
In reply to#108056
Hello World <acidlategamer@gmail.com> writes:
>On Tuesday, April 11, 2017 at 11:04:27 PM UTC+5:30, Scott Lurndal wrote:
>> Hello World <acidlategamer@gmail.com> writes:
>> >Hi all,=20
>> >
>> >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 f=
>> >unction pointers. I wrote this
>> >
>> 
>> >However I get an error
>> >
>> >warning: ISO C forbids assignment between function pointer and =E2=80=98voi=
>> >d *=E2=80=99 [-Wpedantic]
>> >  p =3D malloc(sizeof(p)*4);
>> >    ^
>> >
>> 
>> ISO C forbids that because on some architectures, a function pointer
>> may require more bits than a void pointer contains.[*]
>> 
>> 
>> >What am I missing?
>> 
>> a cast.  (puts on flameproof suit).
>> 
>> [*] On one segmented architecture I used to use, a function pointer required 10-bytes,
>>     whereas a data pointer was 4-bytes.
>
>As far as I know pointer variable have same size in an architecure.

Well, it's clear that your knowledge base is incomplete.

[toc] | [prev] | [next] | [standalone]


#108059

FromHello World <acidlategamer@gmail.com>
Date2017-04-11 10:55 -0700
Message-ID<dc49d12b-d72f-4110-ba2d-d7c83d910d90@googlegroups.com>
In reply to#108057
On Tuesday, April 11, 2017 at 11:18:56 PM UTC+5:30, Scott Lurndal wrote:
> Hello World <acidlategamer@gmail.com> writes:
> >On Tuesday, April 11, 2017 at 11:04:27 PM UTC+5:30, Scott Lurndal wrote:
> >> Hello World <acidlategamer@gmail.com> writes:
> >> >Hi all,=20
> >> >
> >> >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 f=
> >> >unction pointers. I wrote this
> >> >
> >> 
> >> >However I get an error
> >> >
> >> >warning: ISO C forbids assignment between function pointer and =E2=80=98voi=
> >> >d *=E2=80=99 [-Wpedantic]
> >> >  p =3D malloc(sizeof(p)*4);
> >> >    ^
> >> >
> >> 
> >> ISO C forbids that because on some architectures, a function pointer
> >> may require more bits than a void pointer contains.[*]
> >> 
> >> 
> >> >What am I missing?
> >> 
> >> a cast.  (puts on flameproof suit).
> >> 
> >> [*] On one segmented architecture I used to use, a function pointer required 10-bytes,
> >>     whereas a data pointer was 4-bytes.
> >
> >As far as I know pointer variable have same size in an architecure.
> 
> Well, it's clear that your knowledge base is incomplete.
Learn answering skills, before answering. Your answer is too obscure to give a complete picture as what you meant. No reference given to look and increase knowledge base too. 

[toc] | [prev] | [next] | [standalone]


#108064

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2017-04-11 19:06 +0100
Message-ID<87tw5urf7h.fsf@bsb.me.uk>
In reply to#108056
Hello World <acidlategamer@gmail.com> writes:

> On Tuesday, April 11, 2017 at 11:04:27 PM UTC+5:30, Scott Lurndal wrote:
>> Hello World <acidlategamer@gmail.com> writes:
>> >Hi all,=20
>> >
>> >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 f=
>> >unction pointers. I wrote this
>> >
>> 
>> >However I get an error
>> >
>> >warning: ISO C forbids assignment between function pointer and =E2=80=98voi=
>> >d *=E2=80=99 [-Wpedantic]
>> >  p =3D malloc(sizeof(p)*4);
>> >    ^
>> >
>> 
>> ISO C forbids that because on some architectures, a function pointer
>> may require more bits than a void pointer contains.[*]
>> 
>> 
>> >What am I missing?
>> 
>> a cast.  (puts on flameproof suit).
>> 
>> [*] On one segmented architecture I used to use, a function pointer required 10-bytes,
>>     whereas a data pointer was 4-bytes.
>
> As far as I know pointer variable have same size in an architecure.

Please don't get distracted by this.  It makes no difference how large
the pointers are -- you just have a pointer of the wrong type.  See my
other reply to you.

-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#108066

From"James R. Kuyper" <jameskuyper@verizon.net>
Date2017-04-11 14:23 -0400
Message-ID<e5d7075a-311b-365c-eeed-b766ae2f1633@verizon.net>
In reply to#108056
On 04/11/2017 01:42 PM, Hello World wrote:
> On Tuesday, April 11, 2017 at 11:04:27 PM UTC+5:30, Scott Lurndal wrote:
...
>> [*] On one segmented architecture I used to use, a function pointer required 10-bytes,
>>     whereas a data pointer was 4-bytes.
>
> As far as I know pointer variable have same size in an architecure.

That depends entirely on the architecture. The standard imposes no 
requirements on the size of pointers other than those implied by the 
fact that "same representation" necessarily implies "same size", and the 
only cases where it requires that pointers have the same representation 
are the following:

"A pointer to void shall have the same representation and alignment 
requirements as a pointer to a character type.48) Similarly, pointers to 
qualified or unqualified versions of compatible types shall have the 
same representation and alignment requirements. All pointers to 
structure types shall have the same representation and alignment 
requirements as each other. All pointers to union types shall have the 
same representation and alignment requirements as each other. Pointers 
to other types need not have the same representation or alignment 
requirements." (6.2.5p28)

Real world computers with different sizes for data pointers and pointers 
to code are relatively common. Computers where pointers to different 
data types can have different sizes are less common, but they do exist. 
The most common case involves systems where the hardware word size is 
too large to be used as the byte size. On such a system, a pointer to a 
word-aligned data type need only identify the starting word for the 
object it points at. For data types with byte alignment, the pointer 
also needs to identify which byte within a word the object starts at. On 
some systems storing that extra information requires that pointers to 
byte-aligned types be bigger than pointers to word-aligned types.

[toc] | [prev] | [next] | [standalone]


#108063

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2017-04-11 19:05 +0100
Message-ID<87zifmrf9j.fsf@bsb.me.uk>
In reply to#108055
scott@slp53.sl.home (Scott Lurndal) writes:

> Hello World <acidlategamer@gmail.com> writes:
>>
>>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 f=
>>unction pointers. I wrote this
>>
>
>>However I get an error
>>
>>warning: ISO C forbids assignment between function pointer and =E2=80=98voi=
>>d *=E2=80=99 [-Wpedantic]
>>  p =3D malloc(sizeof(p)*4);
>>    ^
>
> ISO C forbids that because on some architectures, a function pointer
> may require more bits than a void pointer contains.[*]
>
>>What am I missing?
>
> a cast.  (puts on flameproof suit).

No!  The OP just needs a pointer of the right type.  A pointer to a
pointer to a function is a plain object pointer pointer type and void *
can be assigned to such a thing without a cast.

-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#108065

From"James R. Kuyper" <jameskuyper@verizon.net>
Date2017-04-11 14:11 -0400
Message-ID<7b6bf43d-6f8a-49b3-4654-ab0f56e7f0e0@verizon.net>
In reply to#108055
On 04/11/2017 01:34 PM, Scott Lurndal wrote:
> Hello World <acidlategamer@gmail.com> writes:
...
>> warning: ISO C forbids assignment between function pointer and =E2=80=98voi=
>> d *=E2=80=99 [-Wpedantic]
>>  p =3D malloc(sizeof(p)*4);
>>    ^
>>
>
> ISO C forbids that because on some architectures, a function pointer
> may require more bits than a void pointer contains.[*]

It's a more fundamental problem than that: functions and objects are two 
completely different types of things, and pointers to functions are 
therefore fundamentally incompatible with pointers to objects.

>> What am I missing?
>
> a cast.  (puts on flameproof suit).

You'll need that suit when the nasal demons come to hunt you down. Where 
would you find the definition of the behavior of such a cast?
6.3.2.3 contains no such definition, which is the place where I'd expect 
it to be if the behavior were defined.

Furthermore, since p is a pointer to a function, once you've allocated 
such memory, you'd have to fill it in with a function. Not a pointer to 
a function, as in the OP's code, but an actual function. How would you 
go about doing that? Hint: attempting to memcpy() a function into that 
memory would fail for the same reason that the assignment above failed.

[toc] | [prev] | [next] | [standalone]


#108073

FromRichard Heathfield <rjh@cpax.org.uk>
Date2017-04-12 08:27 +0100
Message-ID<ockknv$ggf$1@dont-email.me>
In reply to#108065
On 11/04/17 19:11, James R. Kuyper wrote:
> On 04/11/2017 01:34 PM, Scott Lurndal wrote:
>> Hello World <acidlategamer@gmail.com> writes:
> ...
>>> warning: ISO C forbids assignment between function pointer and
>>> =E2=80=98voi=
>>> d *=E2=80=99 [-Wpedantic]
>>>  p =3D malloc(sizeof(p)*4);
>>>    ^
>>>
>>
>> ISO C forbids that because on some architectures, a function pointer
>> may require more bits than a void pointer contains.[*]
>
> It's a more fundamental problem than that: functions and objects are two
> completely different types of things, and pointers to functions are
> therefore fundamentally incompatible with pointers to objects.
>
>>> What am I missing?
>>
>> a cast.  (puts on flameproof suit).
>
> You'll need that suit when the nasal demons come to hunt you down. Where
> would you find the definition of the behavior of such a cast?
> 6.3.2.3 contains no such definition, which is the place where I'd expect
> it to be if the behavior were defined.
>
> Furthermore, since p is a pointer to a function, once you've allocated
> such memory, you'd have to fill it in with a function. Not a pointer to
> a function, as in the OP's code, but an actual function. How would you
> go about doing that? Hint: attempting to memcpy() a function into that
> memory would fail for the same reason that the assignment above failed.

You and Scott have, between you, managed to make this question terribly 
complicated. It was a simple question with a simple, positive answer. 
(In fact, it got the same simple, positive answer more than once, 
because I didn't spot Ben's reply before posting my own.

I suppose, however, that if the simple, positive answer ("yes, it CAN be 
done, and yes, you're NEARLY there, and you just need to tweak THIS 
bit") has been given, we might as well plough a few more furrows in ISO 
9899.

There is one technical point I'd like to make in support of your claim 
that functions and objects are two completely different kinds of things, 
and my point is simply to draw our attention to the existence of this 
well-known software engineering problem:

Objects do, but functions don't.

-- 
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]


#108077

From"James R. Kuyper" <jameskuyper@verizon.net>
Date2017-04-12 13:31 -0400
Message-ID<cc7ef0e0-33b8-e63b-fb00-19de237bfeef@verizon.net>
In reply to#108073
On 04/12/2017 03:27 AM, Richard Heathfield wrote:
...
> You and Scott have, between you, managed to make this question terribly
> complicated. It was a simple question with a simple, positive answer.

You know my style: my answers tend to be as complete and as accurate as 
I can make them, rather than simple. Someone who succeeds in fully 
understanding my answer will have learned a lot more than someone who 
understands  your answer - but on the other hand, they're more likely to 
understand your answer than mine.

When my kids get to the point of asking me why the sky is blue, I'm 
likely to end up trying to explain Rayleigh scattering in terms of 
quantum mechanics to them. They may end up wishing they'd asked someone 
else. :-(

[toc] | [prev] | [next] | [standalone]


#108081

FromRichard Heathfield <rjh@cpax.org.uk>
Date2017-04-12 23:05 +0100
Message-ID<ocm85i$hlb$1@dont-email.me>
In reply to#108077
On 12/04/17 18:31, James R. Kuyper wrote:
<snip>
>
> When my kids get to the point of asking me why the sky is blue, I'm
> likely to end up trying to explain Rayleigh scattering in terms of
> quantum mechanics to them. They may end up wishing they'd asked someone
> else. :-(

Nah, it's because air is blue.

Cf <https://www.xkcd.com/1818/>

-- 
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]


#108061

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2017-04-11 19:03 +0100
Message-ID<8760iastx8.fsf@bsb.me.uk>
In reply to#108054
Hello World <acidlategamer@gmail.com> writes:

> 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);

You don't define some of these.  In fact you don't need the declarations
at all since you refer to the function only after their definitions.

> int (*p)(int a, int b);

Eek!  A "global variable"!  No!

> 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?

When you allocate space of something of type T you get back a pointer
that you store in a variable of type T *.  E.g. you allocate ten ints
and you put the result into a int *:

  int *ints = malloc(10 * sizeof *ints);

The same goes for 4 function pointers.  You need to take the result and
put it a variable of type pointer to function pointer.

These things are simpler with a typedef:

  typedef int operation(int, int);

Now you can make a pointer to a pointer to an "operation" function like
this:

  operation **oplist = malloc(4 * sizeof *oplist);

Some people make the typedef a pointer-to-function type, but I don't
like to hide pointer types behind typedefs and, what's more, this way
you get to declare the functions more easily too:

  operation add, subtract, multiply, divide;

-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#108062

From"James R. Kuyper" <jameskuyper@verizon.net>
Date2017-04-11 14:05 -0400
Message-ID<e49748a6-a681-8c46-583a-8c27ffe4d4f6@verizon.net>
In reply to#108054
On 04/11/2017 01:20 PM, 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, ...

That's not really the case. A C object can have any one of four 
different storage durations: static, thread, automatic, and dynamic. 
Each storage duration had it's own advantages and disadvantages. You 
need to learn what those advantages and disadvantages are, and decide 
for each object which storage duration it should have. Assuming that any 
one storage duration is always best is a mistake that you should avoid 
making.

In particular, one disadvantage of dynamic storage duration is that it 
can be significantly slower than the other types. Another disadvantage 
is that you need to store a pointer to the dynamically allocated memory. 
For both of those reasons, it seldom makes sense to dynamically allocate 
small amounts of memory. I wouldn't ordinarily use it store anything as 
small as four function pointers.

> ... 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);

You're trying to create a dynamically allocated array of pointers to 
functions. That declares p to be a single pointer to a function. What 
you need is:

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);

Attempting to assign a pointer to void to an object containing a pointer 
to a function type is a constraint violation - such an assignment 
doesn't match any of the permitted options listed in 6.5.16.1p1. You 
can't get around this problem by casting the pointer into a pointer to a 
function type, because such a conversion has undefined behavior, because 
the standard doesn't define the behavior of such a conversion. The 
definition (if there were any) would be expected to appear in 6.3.2.3, 
and there is no such definition (except in the special case where the 
pointer being converted is a null pointer - in which case p would 
contain a null pointer to a function. However, if malloc() returns a 
null pointer, no memory has been allocated).

With your original definition, p is a pointer to a function type, and 
the above assignment expression is therefore a constraint violation.
With my revised definition, p is a pointer to an object type. The object 
it points at is a pointer to a function, but p itself can safely be used 
to store the result returned by a call to malloc. However, the call 
should be done differently than you did above:

         p = malloc(4 * sizeof *p);

I changed the order around to avoid any confusion between the two 
different uses of *. malloc(sizeof *p * 4) is perfectly legal, and has 
exactly the same meaning, but is more confusing.

malloc() can fail. If it does, it will return a null pointer. If you 
make any attempt to dereference a null pointer, the behavior is 
undefined. Therefore, every time you call malloc(), you should check for 
the possibility it failed - if it did, you need to skip any code which 
attempts to access the memory that was not, in fact, allocated:

     if(p)
     {

> 	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);

     }

You could move the free() outside the if()-statement, if you wished. One 
of the few things you can safely do with a null pointer is pass it to 
free() - where it will do absolutely nothing. However, there's no point 
in calling free() unless the malloc() call succeeded, so you should 
generally put the free inside the if() statement.

> 	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.

That is exactly correct.

> What am I missing?

One level of indirection: you needed a pointer to a pointer to a 
function, not just a pointer to a function.

[toc] | [prev] | [next] | [standalone]


#108157

FromJorgen Grahn <grahn+nntp@snipabacken.se>
Date2017-04-15 10:19 +0000
Message-ID<slrnof3st4.1jqn.grahn+nntp@frailea.sa.invalid>
In reply to#108062
On Tue, 2017-04-11, James R. Kuyper wrote:
> On 04/11/2017 01:20 PM, 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, ...
>
> That's not really the case. A C object can have any one of four 
> different storage durations: static, thread, automatic, and dynamic. 
> Each storage duration had it's own advantages and disadvantages. You 
> need to learn what those advantages and disadvantages are, and decide 
> for each object which storage duration it should have. Assuming that any 
> one storage duration is always best is a mistake that you should avoid 
> making.
>
> In particular, one disadvantage of dynamic storage duration is that it 
> can be significantly slower than the other types. Another disadvantage 
> is that you need to store a pointer to the dynamically allocated memory. 
> For both of those reasons, it seldom makes sense to dynamically allocate 
> small amounts of memory. I wouldn't ordinarily use it store anything as 
> small as four function pointers.

The worst part about dynamic allocation is IMO the bugs you'll
introduce if you don't plan very carefully: memory leaks, crashes,
use-after-free ... My rule is "when I have to use it, I use it, not
otherwise".

/Jorgen

-- 
  // Jorgen Grahn <grahn@  Oo  o.   .     .
\X/     snipabacken.se>   O  o   .

[toc] | [prev] | [next] | [standalone]


#108158

Fromasetofsymbols@gmail.com
Date2017-04-15 05:09 -0700
Message-ID<f49097c3-490e-48a0-bdb1-eb284219bd3f@googlegroups.com>
In reply to#108157
Dinamic allocation it is all but static allocation;
When someone write
f(){int x;...
That x even if not call malloc it is a "dynamically allocated" object
because it not has a fixed address
in time...

 

[toc] | [prev] | [next] | [standalone]


#108070

FromBarry Schwarz <schwarzb@dqel.com>
Date2017-04-11 15:13 -0700
Message-ID<s1lqec5mkr1fh4ujb7lfulf6ks0rrrkna4@4ax.com>
In reply to#108054
On Tue, 11 Apr 2017 10:20:05 -0700 (PDT), Hello World
<acidlategamer@gmail.com> 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

It's not what you don't know that hurts you; it's what you know that
ain't so.


-- 
Remove del for email

[toc] | [prev] | [next] | [standalone]


#108074

FromRichard Heathfield <rjh@cpax.org.uk>
Date2017-04-12 08:28 +0100
Message-ID<ockkos$ggf$2@dont-email.me>
In reply to#108070
On 11/04/17 23:13, Barry Schwarz wrote:
> On Tue, 11 Apr 2017 10:20:05 -0700 (PDT), Hello World
> <acidlategamer@gmail.com> 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
>
> It's not what you don't know that hurts you; it's what you know that
> ain't so.

What you don't know can be pretty damn deadly too.

-- 
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]


#108072

FromRichard Heathfield <rjh@cpax.org.uk>
Date2017-04-12 08:19 +0100
Message-ID<ockk7b$dkn$1@dont-email.me>
In reply to#108054
On 11/04/17 18:20, 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

Okay, so presumably you effectively want an array of function pointers. 
(Otherwise, why bother with dynamic allocation?)

> #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);

I'm going to use a typedef here, just to keep things tidy (and later on, 
I'll take it out again):

typedef int ft_arithmetic(int, int);

This means: "ft_arithmetic is now a synonym for the /type/ of a function 
that takes two ints and returns int".

We could, in theory, now do this:

ft_arithmetic sum, subt, mul, dive;

but of course we're not going to.

The other things I'm going to do are:

* remove p from file scope. It has no business being there;
* fix p's type;
* fix the malloc argument, which is broken.

> int sum(int a, int b) { return a+b; }

(One-lined only for Usenet brevity, not out of any kind of stylistic 
recommendation!)

> int subtract(int a, int b) { return a-b; }

You prototyped this as 'subt', and you identify it by 'subt' in main(), 
so I presume you meant 'subt', not 'subtract'.

> 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);

Okay, there are several problems here. First, p has the wrong type, and 
secondly, the allocation is wrong.

Note that we could simply write:

         ft_arithmetic *p[4] = { sum, subt, mul, dive };

But of course you want /dynamic/ allocation. So we want:

         ft_arithmetic **p = malloc(4 * sizeof *p);

Translation: p is a pointer. To what /type/ does it point? Let's analogise:

char * ............ points to char
char ** ........... points to char *
int * ............. points to int
int ** ............ points to int *
ft_arithmetic * ... points to ft_arithmetic
ft_arithmetic ** .. points to ft_arithmetic *

So p is a pointer, and the kinds of things it points to are themselves 
pointers (function pointers).

sizeof *p therefore calculates the number of bytes we need for storing a 
pointer to a function of type int(int, int), and 4 * sizeof *p therefore 
gives us the number of bytes we need for storing four such pointers.

The rest of your code was fine.

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));
     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;
}

And here it is again, without the typedef, in case you're the kind of 
person who doesn't like typedefs:

#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 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)
{
   int (**p)(int, int) = 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));
     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;
}


-- 
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]


#108079

FromSpiros Bousbouras <spibou@gmail.com>
Date2017-04-12 21:17 +0000
Message-ID<GPwHA.1005972$Pm3.812399@fx42.am4>
In reply to#108072
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));

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;
> }

[toc] | [prev] | [next] | [standalone]


Page 1 of 2  [1] 2  Next page →

Back to top | Article view | comp.lang.c


csiph-web