Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #396068 > unrolled thread
| Started by | Michael Sanders <porkchop@invalid.foo> |
|---|---|
| First post | 2026-01-02 07:24 +0000 |
| Last post | 2026-01-02 19:44 +0000 |
| Articles | 12 on this page of 72 — 16 participants |
Back to article view | Back to comp.lang.c
function pointer question Michael Sanders <porkchop@invalid.foo> - 2026-01-02 07:24 +0000
Re: function pointer question Lawrence D’Oliveiro <ldo@nz.invalid> - 2026-01-02 09:04 +0000
Re: function pointer question Michael Sanders <porkchop@invalid.foo> - 2026-01-02 14:42 +0000
Re: function pointer question Michael Sanders <porkchop@invalid.foo> - 2026-01-02 14:45 +0000
Re: function pointer question Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2026-01-02 02:52 -0800
Re: function pointer question Michael Sanders <porkchop@invalid.foo> - 2026-01-02 14:43 +0000
Re: function pointer question highcrew <high.crew3868@fastmail.com> - 2026-01-02 17:21 +0100
Re: function pointer question Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2026-01-02 09:37 -0800
Re: function pointer question Ben Bacarisse <ben@bsb.me.uk> - 2026-01-03 03:33 +0000
Re: function pointer question Andrey Tarasevich <noone@noone.net> - 2026-01-03 07:41 -0800
Re: function pointer question Lawrence D’Oliveiro <ldo@nz.invalid> - 2026-01-03 21:46 +0000
Re: function pointer question David Brown <david.brown@hesbynett.no> - 2026-01-04 12:03 +0100
Re: function pointer question Kaz Kylheku <046-301-5902@kylheku.com> - 2026-01-06 20:41 +0000
Re: function pointer question Andrey Tarasevich <noone@noone.net> - 2026-01-07 07:18 -0800
Re: function pointer question Tim Rentsch <tr.17687@z991.linuxsc.com> - 2026-01-07 21:52 -0800
Re: function pointer question David Brown <david.brown@hesbynett.no> - 2026-01-08 09:17 +0100
Re: function pointer question Kaz Kylheku <046-301-5902@kylheku.com> - 2026-01-02 17:48 +0000
Re: function pointer question Michael Sanders <porkchop@invalid.foo> - 2026-01-02 19:35 +0000
Re: function pointer question Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2026-01-02 12:07 -0800
Re: function pointer question Michael Sanders <porkchop@invalid.foo> - 2026-01-03 06:06 +0000
Re: function pointer question Kaz Kylheku <046-301-5902@kylheku.com> - 2026-01-02 21:50 +0000
Re: function pointer question Kaz Kylheku <046-301-5902@kylheku.com> - 2026-01-02 21:52 +0000
Re: function pointer question "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2026-01-02 14:18 -0800
Re: function pointer question David Brown <david.brown@hesbynett.no> - 2026-01-03 13:55 +0100
Re: function pointer question "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2026-01-03 12:04 -0800
Re: function pointer question Andrey Tarasevich <noone@noone.net> - 2026-01-03 13:01 -0800
Re: function pointer question Tim Rentsch <tr.17687@z991.linuxsc.com> - 2026-01-07 07:35 -0800
Re: function pointer question Andrey Tarasevich <noone@noone.net> - 2026-01-07 08:17 -0800
Re: function pointer question Andrey Tarasevich <noone@noone.net> - 2026-01-07 08:23 -0800
Re: function pointer question Tim Rentsch <tr.17687@z991.linuxsc.com> - 2026-01-07 18:44 -0800
Re: function pointer question Tim Rentsch <tr.17687@z991.linuxsc.com> - 2026-01-07 18:27 -0800
Re: function pointer question Lawrence D’Oliveiro <ldo@nz.invalid> - 2026-01-03 22:05 +0000
Re: function pointer question Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2026-01-03 16:39 -0800
Re: function pointer question David Brown <david.brown@hesbynett.no> - 2026-01-04 12:15 +0100
Re: function pointer question Kaz Kylheku <046-301-5902@kylheku.com> - 2026-01-06 20:33 +0000
Re: function pointer question Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2026-01-06 17:01 -0800
Re: function pointer question Michael Sanders <porkchop@invalid.foo> - 2026-01-03 06:08 +0000
Re: function pointer question "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2026-01-05 12:40 -0800
Re: function pointer question Michael Sanders <porkchop@invalid.foo> - 2026-01-06 04:30 +0000
Re: function pointer question "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2026-01-06 17:05 -0800
Re: function pointer question James Kuyper <jameskuyper@alumni.caltech.edu> - 2026-01-03 17:20 -0500
Re: function pointer question Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2026-01-03 16:48 -0800
Re: function pointer question Michael Sanders <porkchop@invalid.foo> - 2026-01-05 08:39 +0000
Re: function pointer question Michael Sanders <porkchop@invalid.foo> - 2026-01-06 12:32 +0000
Re: function pointer question highcrew <high.crew3868@fastmail.com> - 2026-01-06 13:59 +0100
Re: function pointer question Michael Sanders <porkchop@invalid.foo> - 2026-01-06 13:57 +0000
Re: function pointer question antispam@fricas.org (Waldek Hebisch) - 2026-01-06 14:50 +0000
Re: function pointer question highcrew <high.crew3868@fastmail.com> - 2026-01-06 21:44 +0100
Re: function pointer question scott@slp53.sl.home (Scott Lurndal) - 2026-01-06 22:08 +0000
Re: function pointer question Tim Rentsch <tr.17687@z991.linuxsc.com> - 2026-01-07 05:59 -0800
Re: function pointer question antispam@fricas.org (Waldek Hebisch) - 2026-01-07 09:25 +0000
Re: function pointer question David Brown <david.brown@hesbynett.no> - 2026-01-07 11:37 +0100
Re: function pointer question Michael S <already5chosen@yahoo.com> - 2026-01-06 15:47 +0200
Re: function pointer question Michael Sanders <porkchop@invalid.foo> - 2026-01-06 14:01 +0000
Re: function pointer question David Brown <david.brown@hesbynett.no> - 2026-01-06 15:55 +0100
Re: function pointer question Michael Sanders <porkchop@invalid.foo> - 2026-01-06 16:44 +0000
Re: function pointer question scott@slp53.sl.home (Scott Lurndal) - 2026-01-06 15:41 +0000
Re: function pointer question Michael Sanders <porkchop@invalid.foo> - 2026-01-06 16:45 +0000
Re: function pointer question James Kuyper <jameskuyper@alumni.caltech.edu> - 2026-01-06 10:58 -0500
Re: function pointer question Michael Sanders <porkchop@invalid.foo> - 2026-01-06 16:49 +0000
Re: function pointer question James Kuyper <jameskuyper@alumni.caltech.edu> - 2026-01-06 12:09 -0500
Re: function pointer question Michael Sanders <porkchop@invalid.foo> - 2026-01-07 21:18 +0000
Re: function pointer question Tim Rentsch <tr.17687@z991.linuxsc.com> - 2026-01-09 09:14 -0800
Re: function pointer question Andrey Tarasevich <noone@noone.net> - 2026-01-10 19:17 -0800
Re: function pointer question "James Russell Kuyper Jr." <jameskuyper@alumni.caltech.edu> - 2026-01-10 22:39 -0500
Re: function pointer question Tim Rentsch <tr.17687@z991.linuxsc.com> - 2026-01-11 11:49 -0800
Re: function pointer question James Kuyper <jameskuyper@alumni.caltech.edu> - 2026-01-05 06:47 -0500
Re: function pointer question James Kuyper <jameskuyper@alumni.caltech.edu> - 2026-01-02 14:03 -0500
Re: function pointer question Michael Sanders <porkchop@invalid.foo> - 2026-01-02 19:41 +0000
Re: function pointer question bart <bc@freeuk.com> - 2026-01-02 19:18 +0000
Re: function pointer question Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2026-01-02 11:43 -0800
Re: function pointer question Michael Sanders <porkchop@invalid.foo> - 2026-01-02 19:44 +0000
Page 4 of 4 — ← Prev page 1 2 3 [4]
| From | James Kuyper <jameskuyper@alumni.caltech.edu> |
|---|---|
| Date | 2026-01-06 12:09 -0500 |
| Message-ID | <10jjfl6$3jbe4$5@dont-email.me> |
| In reply to | #396223 |
On 2026-01-06 11:49, Michael Sanders wrote: ... > Shoot, its just that I lack at the moment the C-specific vocabulary to > describe what I'm wondering about James. Frustrating trust me =) ... Believe me, I understand. A large part of the messages I post in this forum are devoted to explaining to people the correct terminology, and trying to convince them to use it, in order to avoid confusion. Some people are very resistant to avoiding confusion - they seem to like it. > ... Mainly > its that void seems to be used across multiple contexts (in differing ways). Summarizing what I wrote before, there's exactly three unrelated ways void is used: void foo(int); // Declares that foo does not return any value. int bar(void); // Declares that bar does not take any arguments void *foobar; // Declares that foobar points at an object of unspecified type.
[toc] | [prev] | [next] | [standalone]
| From | Michael Sanders <porkchop@invalid.foo> |
|---|---|
| Date | 2026-01-07 21:18 +0000 |
| Message-ID | <10jmij4$10hfp$1@dont-email.me> |
| In reply to | #396224 |
On Tue, 6 Jan 2026 12:09:58 -0500, James Kuyper wrote: > Believe me, I understand. A large part of the messages I post in this > forum are devoted to explaining to people the correct terminology, and > trying to convince them to use it, in order to avoid confusion. Some > people are very resistant to avoiding confusion - they seem to like it. Oh yeah & I very much appreciate you, Kieth, everyone else too. Its all good, I'll just roll with it & get there a step at a time. > Summarizing what I wrote before, there's exactly three unrelated ways > void is used: > > void foo(int); // Declares that foo does not return any value. > int bar(void); // Declares that bar does not take any arguments > > void *foobar; > // Declares that foobar points at an object of unspecified type. Got it, nice succinct answer. -- :wq Mike Sanders
[toc] | [prev] | [next] | [standalone]
| From | Tim Rentsch <tr.17687@z991.linuxsc.com> |
|---|---|
| Date | 2026-01-09 09:14 -0800 |
| Message-ID | <86cy3in1xt.fsf@linuxsc.com> |
| In reply to | #396216 |
James Kuyper <jameskuyper@alumni.caltech.edu> writes: > On 2026-01-06 07:32, Michael Sanders wrote: > >> On Mon, 5 Jan 2026 08:39:53 -0000 (UTC), Michael Sanders wrote: >> >>> I might have questions down the road... > > In the message you were responding to, I was talking about declarations, > not expressions. > >> One more question, but 1st the context... >> >> I asked ChatGPT this question: >> >> In C, what is the most common meaning of (void) *foo > > I'm curious - in what context did you encounter that code? As written, > it's an expression, and foo would have to be a pointer to an object, That statement is simply wrong. The identifier foo could name a function, or be of type pointer to function, or be of type pointer to an object type (and whose value might or might not point to an object). A compiler might issue a diagnostic if foo has a type that is a pointer to an incomplete object type, but ABICD the C standard doesn't actually require that; the constraint says that the operand "shall have pointer type". > which would be a change of subject from the previous messages in this > thread. > > However, > > (void) *foo; > > would be a declaration equivalent to > > void *foo; > > which is a pointer to void, which would fit the context of our previous > discussion. Could that be what you're actually asking about? In what context is '(void) *foo;' considered a declaration? AFAICT it doesn't satisfy the syntax rules of any version of ISO C.
[toc] | [prev] | [next] | [standalone]
| From | Andrey Tarasevich <noone@noone.net> |
|---|---|
| Date | 2026-01-10 19:17 -0800 |
| Message-ID | <10jv4of$3kiuj$1@dont-email.me> |
| In reply to | #396216 |
On Tue 1/6/2026 7:58 AM, James Kuyper wrote:
>
> However,
>
> (void) *foo;
>
> would be a declaration equivalent to
>
> void *foo;
>
> which is a pointer to void, which would fit the context of our previous
> discussion. Could that be what you're actually asking about?
Um... I believe Tim Rentsch is correct in stating that C declaration
syntax does not allow this. When it comes to 'declaration-specifiers'
portion of the declaration, the grammar is pretty strict in not allowing
and redundant parentheses to slip through. You can't simply parenthesize
the type name and still expect it to match the 'declaration-specifiers'
grammar.
The 'init-declarator-list' side is way more permissive in that regard
int (a); /* equivalent to `int a;` */
but not what you stated above.
P.S. On a loosely related note: the C++-like grammatical ambiguity
between a function call and a declaration, present in
{ foo(x); }
is technically present in C as well, but it is prevented by the fact
that there's simply no way to declare `foo` as a function and as a
typedef name without having one name hide another.
--
Best regards,
Andrey
[toc] | [prev] | [next] | [standalone]
| From | "James Russell Kuyper Jr." <jameskuyper@alumni.caltech.edu> |
|---|---|
| Date | 2026-01-10 22:39 -0500 |
| Message-ID | <10jv61p$15aeb$2@dont-email.me> |
| In reply to | #396338 |
On 2026-01-10 22:17, Andrey Tarasevich wrote:
> On Tue 1/6/2026 7:58 AM, James Kuyper wrote:
>>
>> However,
>>
>> (void) *foo;
>>
>> would be a declaration equivalent to
>>
>> void *foo;
>>
>> which is a pointer to void, which would fit the context of our previous
>> discussion. Could that be what you're actually asking about?
>
> Um... I believe Tim Rentsch is correct in stating that C declaration
> syntax does not allow this. When it comes to 'declaration-specifiers'
> portion of the declaration, the grammar is pretty strict in not allowing
> and redundant parentheses to slip through. You can't simply parenthesize
> the type name and still expect it to match the 'declaration-specifiers'
> grammar.
>
> The 'init-declarator-list' side is way more permissive in that regard
>
> int (a); /* equivalent to `int a;` */
>
> but not what you stated above.
>
> P.S. On a loosely related note: the C++-like grammatical ambiguity
> between a function call and a declaration, present in
>
> { foo(x); }
>
> is technically present in C as well, but it is prevented by the fact
> that there's simply no way to declare `foo` as a function and as a
> typedef name without having one name hide another.
>
I had remembered that parantheses could be optionally (and pointlessly)
added surrounding a declarator (6.7.7.1p6). Since it's a feature I would
never bother using, I didn't pay much attention to the details, and
forgot that it applies only to the declarator. I should have checked
before posting.
[toc] | [prev] | [next] | [standalone]
| From | Tim Rentsch <tr.17687@z991.linuxsc.com> |
|---|---|
| Date | 2026-01-11 11:49 -0800 |
| Message-ID | <864ioslykw.fsf@linuxsc.com> |
| In reply to | #396338 |
Andrey Tarasevich <noone@noone.net> writes: > On Tue 1/6/2026 7:58 AM, James Kuyper wrote: > >> However, >> >> (void) *foo; >> >> would be a declaration equivalent to >> >> void *foo; >> >> which is a pointer to void, which would fit the context of our previous >> discussion. Could that be what you're actually asking about? > > Um... I believe Tim Rentsch is correct in stating that C declaration > syntax does not allow this. [...] Thanks Andrey. :)
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@alumni.caltech.edu> |
|---|---|
| Date | 2026-01-05 06:47 -0500 |
| Message-ID | <10jg8cp$26t30$3@dont-email.me> |
| In reply to | #396122 |
On 2026-01-03 17:20, James Kuyper wrote: ... >> char str[] = "learning publicly is a humbling experience."; > 12345678901234567890\ >> char *ptr = str; > In this case, str has the type "char[ I got interrupted while composing that message, and sent it with that part incomplete. It should have said "has the type char[44]", and I had intended to remove the digits I was typing to confirm the length of the string.
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@alumni.caltech.edu> |
|---|---|
| Date | 2026-01-02 14:03 -0500 |
| Message-ID | <10j94qk$k5r3$2@dont-email.me> |
| In reply to | #396068 |
On 2026-01-02 02:24, Michael Sanders wrote: > i have: > > void moo(char HISTORY[][64], int hst_len, int invalid, const char > *gme_msg) > > void mastermind(char HISTORY[][64], int hst_len, int invalid, const > char *gme_msg) > > to use either i have: > > void (*render)(char [][64], int, int, const char *) = MOO ? moo : > mastermind; > > my multi-part question: > > why is void required for the function pointer? Because otherwise you would have to cast each function to match the type of the function pointer before assigning it. > A: because both moo() & mastermind return void? You can safely convert any function pointer to any other function pointer type. However, you must convert it back to a a pointer to a function type that is compatible with the function itself before using the pointer to call that function. The simplest way to deal with that fact is to make sure that all the functions that you might want the pointer to point at have the same type, and then just declare it as a pointer to that type. The more complicated approach requires you to keep track in some fashion what the original function type was, and to convert it back to that type before dereferencing it. There are rare situations where this is worth doing, but in general you should avoid this approach. > B: because every function must have a return type > *including function pointers*? Well, that's true, but what I said about compatibility of a function pointer with a function's actual type is the more important issue, and implies what you've said above. > C: what about tyedef? You'll need to explain what you your question about typedef is. Here's the key thing you need to know: a typedef does not declare a new type, it merely provides an alias for a type. If you replace every occurrence of a typedef with the type it's a defined as an alias of, your code should work exactly the same.
[toc] | [prev] | [next] | [standalone]
| From | Michael Sanders <porkchop@invalid.foo> |
|---|---|
| Date | 2026-01-02 19:41 +0000 |
| Message-ID | <10j970c$ljll$1@dont-email.me> |
| In reply to | #396082 |
On Fri, 2 Jan 2026 14:03:48 -0500, James Kuyper wrote: > On 2026-01-02 02:24, Michael Sanders wrote: >> i have: >> >> void moo(char HISTORY[][64], int hst_len, int invalid, const char >> *gme_msg) >> >> void mastermind(char HISTORY[][64], int hst_len, int invalid, const >> char *gme_msg) >> >> to use either i have: >> >> void (*render)(char [][64], int, int, const char *) = MOO ? moo : >> mastermind; >> >> my multi-part question: >> >> why is void required for the function pointer? > > Because otherwise you would have to cast each function to match the type > of the function pointer before assigning it. > >> A: because both moo() & mastermind return void? > > You can safely convert any function pointer to any other function > pointer type. However, you must convert it back to a a pointer to a > function type that is compatible with the function itself before using > the pointer to call that function. > The simplest way to deal with that fact is to make sure that all the > functions that you might want the pointer to point at have the same > type, and then just declare it as a pointer to that type. > The more complicated approach requires you to keep track in some fashion > what the original function type was, and to convert it back to that type > before dereferencing it. There are rare situations where this is worth > doing, but in general you should avoid this approach. > >> B: because every function must have a return type >> *including function pointers*? > > Well, that's true, but what I said about compatibility of a function > pointer with a function's actual type is the more important issue, and > implies what you've said above. > >> C: what about tyedef? > > You'll need to explain what you your question about typedef is. Here's > the key thing you need to know: a typedef does not declare a new type, > it merely provides an alias for a type. If you replace every occurrence > of a typedef with the type it's a defined as an alias of, your code > should work exactly the same. This post is going into my notes! A bag of 'thank you's James. -- :wq Mike Sanders
[toc] | [prev] | [next] | [standalone]
| From | bart <bc@freeuk.com> |
|---|---|
| Date | 2026-01-02 19:18 +0000 |
| Message-ID | <10j95n0$kkj4$1@dont-email.me> |
| In reply to | #396068 |
On 02/01/2026 07:24, Michael Sanders wrote:
> i have:
>
> void moo(char HISTORY[][64], int hst_len, int invalid, const char *gme_msg)
>
> void mastermind(char HISTORY[][64], int hst_len, int invalid, const char *gme_msg)
>
> to use either i have:
>
> void (*render)(char [][64], int, int, const char *) = MOO ? moo : mastermind;
>
> my multi-part question:
>
> why is void required for the function pointer?
>
> A: because both moo() & mastermind return void?
Neither return anything. But in C there is no special syntax to denote
routines that don't return values. So a dummy 'void' return type is used.
>
> B: because every function must have a return type
> *including function pointers*?
If you have any function that returns type T (including when T is void
like your examples), then its type is 'function(...)returning T'.
A pointer to such a function will have a type:
'pointer to function(...)returning T'.
In C syntax, that return type always goes at the start of the
declaration. In your examples, that will be 'void'.
> C: what about tyedef?
Typedefs create convenient aliases for types. So if you created an alias
U for that pointer type in my last example, then you can subsequently
just use U:
U p, q, r;
This declares three variable all with type 'pointer to ... void'. So in
this case the details are hidden, including that void.
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <Keith.S.Thompson+u@gmail.com> |
|---|---|
| Date | 2026-01-02 11:43 -0800 |
| Message-ID | <87zf6vu7ga.fsf@example.invalid> |
| In reply to | #396083 |
bart <bc@freeuk.com> writes:
[...]
> If you have any function that returns type T (including when T is void
> like your examples), then its type is 'function(...)returning T'.
>
> A pointer to such a function will have a type:
>
> 'pointer to function(...)returning T'.
[...]
Just to clarify, the "..." refers to the list of parameter types, in
this case "pointer to function(char [][64], int, int, const char *)
returning void)". It's not a literal `...` token.
I mention this because `void func(...)` is valid starting in C23; it's a
variadic function with no fixed parameters. `void func(...)` is not
compatible with, for example, `void(int)`.
--
Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
void Void(void) { Void(); } /* The recursive call of the void */
[toc] | [prev] | [next] | [standalone]
| From | Michael Sanders <porkchop@invalid.foo> |
|---|---|
| Date | 2026-01-02 19:44 +0000 |
| Message-ID | <10j976j$ljll$2@dont-email.me> |
| In reply to | #396083 |
On Fri, 2 Jan 2026 19:18:56 +0000, bart wrote: > On 02/01/2026 07:24, Michael Sanders wrote: >> i have: >> >> void moo(char HISTORY[][64], int hst_len, int invalid, const char *gme_msg) >> >> void mastermind(char HISTORY[][64], int hst_len, int invalid, const char *gme_msg) >> >> to use either i have: >> >> void (*render)(char [][64], int, int, const char *) = MOO ? moo : mastermind; >> >> my multi-part question: >> >> why is void required for the function pointer? >> >> A: because both moo() & mastermind return void? > > Neither return anything. But in C there is no special syntax to denote > routines that don't return values. So a dummy 'void' return type is used. > >> >> B: because every function must have a return type >> *including function pointers*? > > If you have any function that returns type T (including when T is void > like your examples), then its type is 'function(...)returning T'. > > A pointer to such a function will have a type: > > 'pointer to function(...)returning T'. > > In C syntax, that return type always goes at the start of the > declaration. In your examples, that will be 'void'. > >> C: what about tyedef? > > Typedefs create convenient aliases for types. So if you created an alias > U for that pointer type in my last example, then you can subsequently > just use U: > > U p, q, r; > > This declares three variable all with type 'pointer to ... void'. So in > this case the details are hidden, including that void. Yes I'm starting to see it now in my mind's eye. Especially: 'So a dummy 'void' return type is used.' These are superb answers guys =) -- :wq Mike Sanders
[toc] | [prev] | [standalone]
Page 4 of 4 — ← Prev page 1 2 3 [4]
Back to top | Article view | comp.lang.c
csiph-web