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


Groups > comp.unix.programmer > #14059 > unrolled thread

Question about Linux/gcc and the signal() function prototype.

Started bygazelle@shell.xmission.com (Kenny McCormack)
First post2022-11-25 11:39 +0000
Last post2022-11-28 11:47 +0000
Articles 11 — 7 participants

Back to article view | Back to comp.unix.programmer


Contents

  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. Nicolas George <nicolas$george@salle-s.org> - 2022-11-25 13:05 +0000
          Re: Question about Linux/gcc and the signal() function prototype. gazelle@shell.xmission.com (Kenny McCormack) - 2022-11-25 14:01 +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

#14059 — Question about Linux/gcc and the signal() function prototype.

Fromgazelle@shell.xmission.com (Kenny McCormack)
Date2022-11-25 11:39 +0000
SubjectQuestion 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]


#14060

FromRalf Fassel <ralfixx@gmx.de>
Date2022-11-25 13:03 +0100
Message-ID<ygazgcftf5r.fsf@akutech.de>
In reply to#14059
* 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]


#14061

Fromgazelle@shell.xmission.com (Kenny McCormack)
Date2022-11-25 12:28 +0000
Message-ID<tlqce3$fuhb$2@news.xmission.com>
In reply to#14060
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]


#14062

FromNicolas George <nicolas$george@salle-s.org>
Date2022-11-25 13:05 +0000
Message-ID<6380bd9d$0$3065$426a74cc@news.free.fr>
In reply to#14061
Kenny McCormack, dans le message <tlqce3$fuhb$2@news.xmission.com>, a
 écrit :
> 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").

SYNOPSIS
       #include <signal.h>

       typedef void (*sighandler_t)(int);

       sighandler_t signal(int signum, sighandler_t handler);

All we need to know is there.

Except…

> That's the C way...

Yes, knowledge of the C programming language, how to read type declarations
and so on, is an implicit prerequisite.

> All of this seems to be an artifact of the fact that functions and pointers
> to functions are (basically) the same thing.

No they are not.

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


#14063

Fromgazelle@shell.xmission.com (Kenny McCormack)
Date2022-11-25 14:01 +0000
Message-ID<tlqhsi$g48c$1@news.xmission.com>
In reply to#14062
In article <6380bd9d$0$3065$426a74cc@news.free.fr>,
Nicolas George  <nicolas$george@salle-s.org> wrote:
>Kenny McCormack, dans le message <tlqce3$fuhb$2@news.xmission.com>, a
> crit:
>> 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").
>
>SYNOPSIS
>       #include <signal.h>
>
>       typedef void (*sighandler_t)(int);
>
>       sighandler_t signal(int signum, sighandler_t handler);
>
>All we need to know is there.
>
>Except
>
>> That's the C way...
>
>Yes, knowledge of the C programming language, how to read type declarations
>and so on, is an implicit prerequisite.
>
>> All of this seems to be an artifact of the fact that functions and pointers
>> to functions are (basically) the same thing.
>
>No they are not.

What a totally stupid response.

You hit all the marks.  Congrats.

-- 
I love the poorly educated.

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


#14064

Fromscott@slp53.sl.home (Scott Lurndal)
Date2022-11-25 16:57 +0000
Message-ID<3u6gL.4180$lhOe.1802@fx06.iad>
In reply to#14061
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]


#14069

FromRainer Weikusat <rweikusat@talktalk.net>
Date2022-11-27 12:27 +0000
Message-ID<87lenwfuq4.fsf@doppelsaurus.mobileactivedefense.com>
In reply to#14061
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]


#14071

Fromgazelle@shell.xmission.com (Kenny McCormack)
Date2022-11-27 13:06 +0000
Message-ID<tlvncc$im4v$1@news.xmission.com>
In reply to#14069
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]


#14072

FromKaz Kylheku <864-117-4973@kylheku.com>
Date2022-11-28 00:43 +0000
Message-ID<20221127164105.872@kylheku.com>
In reply to#14071
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]


#14073

FromRichard Damon <Richard@Damon-Family.org>
Date2022-11-27 21:39 -0500
Message-ID<_bVgL.117758$8875.113548@fx13.iad>
In reply to#14072
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]


#14074

FromRainer Weikusat <rweikusat@talktalk.net>
Date2022-11-28 11:47 +0000
Message-ID<87lenvuwq6.fsf@doppelsaurus.mobileactivedefense.com>
In reply to#14072
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.unix.programmer


csiph-web