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 | 20 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 1 of 2 [1] 2 Next page →
| From | Hello World <acidlategamer@gmail.com> |
|---|---|
| Date | 2017-04-11 10:20 -0700 |
| Subject | correct 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]
| From | scott@slp53.sl.home (Scott Lurndal) |
|---|---|
| Date | 2017-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]
| From | Hello World <acidlategamer@gmail.com> |
|---|---|
| Date | 2017-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]
| From | scott@slp53.sl.home (Scott Lurndal) |
|---|---|
| Date | 2017-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]
| From | Hello World <acidlategamer@gmail.com> |
|---|---|
| Date | 2017-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]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2017-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]
| From | "James R. Kuyper" <jameskuyper@verizon.net> |
|---|---|
| Date | 2017-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]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2017-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]
| From | "James R. Kuyper" <jameskuyper@verizon.net> |
|---|---|
| Date | 2017-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]
| From | Richard Heathfield <rjh@cpax.org.uk> |
|---|---|
| Date | 2017-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]
| From | "James R. Kuyper" <jameskuyper@verizon.net> |
|---|---|
| Date | 2017-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]
| From | Richard Heathfield <rjh@cpax.org.uk> |
|---|---|
| Date | 2017-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]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2017-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]
| From | "James R. Kuyper" <jameskuyper@verizon.net> |
|---|---|
| Date | 2017-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]
| From | Jorgen Grahn <grahn+nntp@snipabacken.se> |
|---|---|
| Date | 2017-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]
| From | asetofsymbols@gmail.com |
|---|---|
| Date | 2017-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]
| From | Barry Schwarz <schwarzb@dqel.com> |
|---|---|
| Date | 2017-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]
| From | Richard Heathfield <rjh@cpax.org.uk> |
|---|---|
| Date | 2017-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]
| From | Richard Heathfield <rjh@cpax.org.uk> |
|---|---|
| Date | 2017-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]
| From | Spiros Bousbouras <spibou@gmail.com> |
|---|---|
| Date | 2017-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