Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #168346 > unrolled thread
| Started by | gazelle@shell.xmission.com (Kenny McCormack) |
|---|---|
| First post | 2022-11-25 11:39 +0000 |
| Last post | 2022-11-28 11:47 +0000 |
| Articles | 9 — 6 participants |
Back to article view | Back to comp.lang.c
Question about Linux/gcc and the signal() function prototype. gazelle@shell.xmission.com (Kenny McCormack) - 2022-11-25 11:39 +0000
Re: Question about Linux/gcc and the signal() function prototype. Ralf Fassel <ralfixx@gmx.de> - 2022-11-25 13:03 +0100
Re: Question about Linux/gcc and the signal() function prototype. gazelle@shell.xmission.com (Kenny McCormack) - 2022-11-25 12:28 +0000
Re: Question about Linux/gcc and the signal() function prototype. scott@slp53.sl.home (Scott Lurndal) - 2022-11-25 16:57 +0000
Re: Question about Linux/gcc and the signal() function prototype. Rainer Weikusat <rweikusat@talktalk.net> - 2022-11-27 12:27 +0000
Re: Question about Linux/gcc and the signal() function prototype. gazelle@shell.xmission.com (Kenny McCormack) - 2022-11-27 13:06 +0000
Re: Question about Linux/gcc and the signal() function prototype. Kaz Kylheku <864-117-4973@kylheku.com> - 2022-11-28 00:43 +0000
Re: Question about Linux/gcc and the signal() function prototype. Richard Damon <Richard@Damon-Family.org> - 2022-11-27 21:39 -0500
Re: Question about Linux/gcc and the signal() function prototype. Rainer Weikusat <rweikusat@talktalk.net> - 2022-11-28 11:47 +0000
| From | gazelle@shell.xmission.com (Kenny McCormack) |
|---|---|
| Date | 2022-11-25 11:39 +0000 |
| Subject | Question about Linux/gcc and the signal() function prototype. |
| Message-ID | <tlq9hg$fuhb$1@news.xmission.com> |
Note: This question is very Linux and gcc specific. You've been warned!
Also, don't bother picking nits like how main() is declared or whether or
not to use the word "stack" in polite company. Thanks.
I have a small C program that looks basically like:
#define _GNU_SOURCE
#include <signal.h>
...
sighandler_t myhandler(int sig)
{
...
}
int main(void)
{
...
signal(1,myhandler);
...
}
I compile with the usual: -W -Wall -Werror
and get these errors:
$ gcc ...
MyTest.c: In function 'main':
MyTest.c:22:40: error: passing argument 2 of 'signal' from incompatible pointer type [-Werror]
signal(1,myhandler);
^
In file included from MyTest.c:7:0:
/usr/include/signal.h:102:23: note: expected '__sighandler_t' but argument is of type 'void (* (*)(int))(int)'
extern __sighandler_t signal (int __sig, __sighandler_t __handler)
^
Now, I can make this go away in either of two ways:
1) Change the call to signal to:
signal(1,(sighandler_t) myhandler);
or
2) Remove the #define _GNU_SOURCE and then:
a) Declare myhandler as "sig_t" instead of "sighandler_t".
b) Change the call to signal to:
signal(1,(sig_t) myhandler);
But the point is that in either case, a cast in the signal() call seems
to be required. Why is this?
Note that the myhandler() function is declared/defined before main(), so it
should "just work", shouldn't it?
--
Joni Ernst (2014): Obama should be impeached because 2 people have died of Ebola.
Joni Ernst (2020): Trump is doing great things, because only 65,000 times as many people have died of COVID-19.
Josef Stalin (1947): When one person dies, it is a tragedy; when a million die, it is merely statistics.
[toc] | [next] | [standalone]
| From | Ralf Fassel <ralfixx@gmx.de> |
|---|---|
| Date | 2022-11-25 13:03 +0100 |
| Message-ID | <ygazgcftf5r.fsf@akutech.de> |
| In reply to | #168346 |
* gazelle@shell.xmission.com (Kenny McCormack)
| Note: This question is very Linux and gcc specific. You've been warned!
| Also, don't bother picking nits like how main() is declared or whether or
| not to use the word "stack" in polite company. Thanks.
>
| I have a small C program that looks basically like:
>
| #define _GNU_SOURCE
| #include <signal.h>
>
| ...
>
| sighandler_t myhandler(int sig)
| {
| ...
| }
I think that according to signal(2) that should rather be
void myhandler(int sig) {
...
}
NAME
signal - ANSI C signal handling
SYNOPSIS
#include <signal.h>
typedef void (*sighandler_t)(int);
Note that 'sighandler_t' is the typedef for the _signal handler_ (to be
used in the declaration of signal()), not the return value of the signal
handler. The return value of the signal handler is void, taking one
integer argument.
R'
[toc] | [prev] | [next] | [standalone]
| From | gazelle@shell.xmission.com (Kenny McCormack) |
|---|---|
| Date | 2022-11-25 12:28 +0000 |
| Message-ID | <tlqce3$fuhb$2@news.xmission.com> |
| In reply to | #168347 |
In article <ygazgcftf5r.fsf@akutech.de>, Ralf Fassel <ralfixx@gmx.de> wrote:
...
>I think that according to signal(2) that should rather be
>
> void myhandler(int sig) {
> ...
> }
>
>
> NAME
> signal - ANSI C signal handling
> SYNOPSIS
> #include <signal.h>
> typedef void (*sighandler_t)(int);
>
>Note that 'sighandler_t' is the typedef for the _signal handler_ (to be
>used in the declaration of signal()), not the return value of the signal
>handler. The return value of the signal handler is void, taking one
>integer argument.
Yes, thanks. That seems to fix things.
The funny thing is that (at least on my system), nowhere in "man signal"
does it actually tell you how to declare the signal handler function (that
is, as simply "void"). You could say that this is implicit in saying that
sighandler_t is a pointer to a void function, so the thing must itself be a
void function.
That's the C way...
All of this seems to be an artifact of the fact that functions and pointers
to functions are (basically) the same thing. This isn't true for any other
type of object.
--
Trump - the President for the rest of us.
https://www.youtube.com/watch?v=JSkUJKgdcoE
[toc] | [prev] | [next] | [standalone]
| From | scott@slp53.sl.home (Scott Lurndal) |
|---|---|
| Date | 2022-11-25 16:57 +0000 |
| Message-ID | <3u6gL.4180$lhOe.1802@fx06.iad> |
| In reply to | #168348 |
gazelle@shell.xmission.com (Kenny McCormack) writes:
>In article <ygazgcftf5r.fsf@akutech.de>, Ralf Fassel <ralfixx@gmx.de> wrote:
>...
>>I think that according to signal(2) that should rather be
>>
>> void myhandler(int sig) {
>> ...
>> }
>>
>>
>> NAME
>> signal - ANSI C signal handling
>> SYNOPSIS
>> #include <signal.h>
>> typedef void (*sighandler_t)(int);
>>
>>Note that 'sighandler_t' is the typedef for the _signal handler_ (to be
>>used in the declaration of signal()), not the return value of the signal
>>handler. The return value of the signal handler is void, taking one
>>integer argument.
>
>Yes, thanks. That seems to fix things.
>
>The funny thing is that (at least on my system), nowhere in "man signal"
>does it actually tell you how to declare the signal handler function (that
>is, as simply "void"). You could say that this is implicit in saying that
>sighandler_t is a pointer to a void function, so the thing must itself be a
>void function.
FWIW, when using unix, linux or any POSIX based system, I'd recommend
using 'sigaction' rather than 'signal'.
[toc] | [prev] | [next] | [standalone]
| From | Rainer Weikusat <rweikusat@talktalk.net> |
|---|---|
| Date | 2022-11-27 12:27 +0000 |
| Message-ID | <87lenwfuq4.fsf@doppelsaurus.mobileactivedefense.com> |
| In reply to | #168348 |
gazelle@shell.xmission.com (Kenny McCormack) writes: [sighandler_t confusion] > All of this seems to be an artifact of the fact that functions and pointers > to functions are (basically) the same thing. This isn't true for any other > type of object. It's basically the same as with array types: An object which has a function type is automatically converted to a pointer to a function when used as argument of something. But they're nevertheless distinct. Stevens uses typedef void sighandler(int); sighandler *signal(int, sighandler *); in newer editions of APUE.
[toc] | [prev] | [next] | [standalone]
| From | gazelle@shell.xmission.com (Kenny McCormack) |
|---|---|
| Date | 2022-11-27 13:06 +0000 |
| Message-ID | <tlvncc$im4v$1@news.xmission.com> |
| In reply to | #168359 |
In article <87lenwfuq4.fsf@doppelsaurus.mobileactivedefense.com>, Rainer Weikusat <rweikusat@talktalk.net> wrote: >gazelle@shell.xmission.com (Kenny McCormack) writes: > >[sighandler_t confusion] > >> All of this seems to be an artifact of the fact that functions and pointers >> to functions are (basically) the same thing. This isn't true for any other >> type of object. > >It's basically the same as with array types: An object which has a function >type is automatically converted to a pointer to a function when used as >argument of something. But they're nevertheless distinct. Stevens uses > >typedef void sighandler(int); >sighandler *signal(int, sighandler *); > >in newer editions of APUE. Yes. That makes more sense. Probably won't ever get fixed, though. -- The randomly chosen signature file that would have appeared here is more than 4 lines long. As such, it violates one or more Usenet RFCs. In order to remain in compliance with said RFCs, the actual sig can be found at the following URL: http://user.xmission.com/~gazelle/Sigs/WeekendAwayFromHome
[toc] | [prev] | [next] | [standalone]
| From | Kaz Kylheku <864-117-4973@kylheku.com> |
|---|---|
| Date | 2022-11-28 00:43 +0000 |
| Message-ID | <20221127164105.872@kylheku.com> |
| In reply to | #168362 |
On 2022-11-27, Kenny McCormack <gazelle@shell.xmission.com> wrote:
> In article <87lenwfuq4.fsf@doppelsaurus.mobileactivedefense.com>,
> Rainer Weikusat <rweikusat@talktalk.net> wrote:
>>gazelle@shell.xmission.com (Kenny McCormack) writes:
>>
>>[sighandler_t confusion]
>>
>>> All of this seems to be an artifact of the fact that functions and pointers
>>> to functions are (basically) the same thing. This isn't true for any other
>>> type of object.
>>
>>It's basically the same as with array types: An object which has a function
>>type is automatically converted to a pointer to a function when used as
>>argument of something. But they're nevertheless distinct. Stevens uses
>>
>>typedef void sighandler(int);
>>sighandler *signal(int, sighandler *);
>>
>>in newer editions of APUE.
>
> Yes. That makes more sense.
>
> Probably won't ever get fixed, though.
With sighandler defined that way, you can do this:
sighandler myhandler; // forward declaration of your handler
void myhandler(int) // ... but no way of using sighandler for defining
{
}
It has little value compared to just making a typedef for the pointer.
--
TXR Programming Language: http://nongnu.org/txr
Cygnal: Cygwin Native Application Library: http://kylheku.com/cygnal
[toc] | [prev] | [next] | [standalone]
| From | Richard Damon <Richard@Damon-Family.org> |
|---|---|
| Date | 2022-11-27 21:39 -0500 |
| Message-ID | <_bVgL.117758$8875.113548@fx13.iad> |
| In reply to | #168371 |
On 11/27/22 7:43 PM, Kaz Kylheku wrote:
> On 2022-11-27, Kenny McCormack <gazelle@shell.xmission.com> wrote:
>> In article <87lenwfuq4.fsf@doppelsaurus.mobileactivedefense.com>,
>> Rainer Weikusat <rweikusat@talktalk.net> wrote:
>>> gazelle@shell.xmission.com (Kenny McCormack) writes:
>>>
>>> [sighandler_t confusion]
>>>
>>>> All of this seems to be an artifact of the fact that functions and pointers
>>>> to functions are (basically) the same thing. This isn't true for any other
>>>> type of object.
>>>
>>> It's basically the same as with array types: An object which has a function
>>> type is automatically converted to a pointer to a function when used as
>>> argument of something. But they're nevertheless distinct. Stevens uses
>>>
>>> typedef void sighandler(int);
>>> sighandler *signal(int, sighandler *);
>>>
>>> in newer editions of APUE.
>>
>> Yes. That makes more sense.
>>
>> Probably won't ever get fixed, though.
>
> With sighandler defined that way, you can do this:
>
> sighandler myhandler; // forward declaration of your handler
>
> void myhandler(int) // ... but no way of using sighandler for defining
> {
> }
>
> It has little value compared to just making a typedef for the pointer.
>
The one advantage is if the definition disagrees with the forward
declaration, you will get a diagnostic, likely an error.
[toc] | [prev] | [next] | [standalone]
| From | Rainer Weikusat <rweikusat@talktalk.net> |
|---|---|
| Date | 2022-11-28 11:47 +0000 |
| Message-ID | <87lenvuwq6.fsf@doppelsaurus.mobileactivedefense.com> |
| In reply to | #168371 |
Kaz Kylheku <864-117-4973@kylheku.com> writes:
> On 2022-11-27, Kenny McCormack <gazelle@shell.xmission.com> wrote:
>> In article <87lenwfuq4.fsf@doppelsaurus.mobileactivedefense.com>,
>> Rainer Weikusat <rweikusat@talktalk.net> wrote:
>>>gazelle@shell.xmission.com (Kenny McCormack) writes:
>>>
>>>[sighandler_t confusion]
>>>
>>>> All of this seems to be an artifact of the fact that functions and pointers
>>>> to functions are (basically) the same thing. This isn't true for any other
>>>> type of object.
>>>
>>>It's basically the same as with array types: An object which has a function
>>>type is automatically converted to a pointer to a function when used as
>>>argument of something. But they're nevertheless distinct. Stevens uses
>>>
>>>typedef void sighandler(int);
>>>sighandler *signal(int, sighandler *);
>>>
>>>in newer editions of APUE.
>>
>> Yes. That makes more sense.
>>
>> Probably won't ever get fixed, though.
>
> With sighandler defined that way, you can do this:
>
> sighandler myhandler; // forward declaration of your handler
>
> void myhandler(int) // ... but no way of using sighandler for defining
> {
> }
>
> It has little value compared to just making a typedef for the pointer.
This calls the following "famous wast lard" to mind (from the GLib
documentation)
typedef void *gpointer;
Gpointer is the GLib way of declaring a pointer to void. It looks better
than void * and is easier to use.
For people who don't belong to the I-have-to-use-C-but-hate-it!!1
faction, pointers are declared by suffixing a base type with *. Hence,
creating a typedef for the function type and deriving a pointer type
from that by suffixing it with * is consistent with the type system of
the language in general while using typedef to hide the * isn't.
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.c
csiph-web