Comparisons with value returned from "signal". 
Author Message
 Comparisons with value returned from "signal".

The standard library function "signal" has the following prototype:

   void (* signal (int sig, void (* handler) (int))) (int);

Hence, it returns a pointer to a function that takes an int and
returns void.  Now, according to K&R2, the return value will
be a pointer to the previous handler for the given signal, or
SIG_ERR if an error occurs.  So presumably, it is intended that
one be able to utilize it as follows:

   old_handler = signal (sig, new_handler);
   if (old_handler == SIG_ERR) {
      /*  Deal with error.  */
   }
   /*  Continue, since signal handler  */
   /*  registration succeeded.         */

But I was under the impression that a pointer could only be
compared to one of two things - (1) a pointer to an object
in the same array that the first pointer points into, or
(2) a null pointer (or a constant integral-type zero).
The value returned by "signal" is a pointer to a function,
not a pointer to an object, so the first possibility is
ruled out even if "signal" keeps all the signal handler
pointers in a common array.  So does this mean that SIG_ERR
is actually a null pointer, or is the comparison I showed
above not legal, or do I misunderstand the rules on pointer
comparisons?



Wed, 31 Mar 2004 16:27:51 GMT  
 Comparisons with value returned from "signal".

Quote:

>    old_handler = signal (sig, new_handler);
>    if (old_handler == SIG_ERR) {
>       /*  Deal with error.  */
>    }
>    /*  Continue, since signal handler  */
>    /*  registration succeeded.         */

     This is correct.

Quote:
> But I was under the impression that a pointer could only be
> compared to one of two things - (1) a pointer to an object
> in the same array that the first pointer points into, or
> (2) a null pointer (or a constant integral-type zero).

     For inequality, you can also compare it to a different
object of the same type.  SIG_ERR counts as a different object of
the same type.

Tak-Shing



Wed, 31 Mar 2004 16:46:07 GMT  
 Comparisons with value returned from "signal".

Quote:

>      For inequality, you can also compare it to a different
> object of the same type.  SIG_ERR counts as a different object of
> the same type.

     My last post was not quite accurate; here is a better one
written in pedantic mode.

     On conforming implementations, upon inclusion of <signal.h>,
SIG_ERR is guaranteed to be a macro expanding to a constant
expression with ``distinct values that have type compatible with
the second argument to, and the return value of, the signal
function and whose values compare unequal to the address of any
declarable function'' (7.14 #3).

     Second, for the equality or inequality operators, if the
first operand is the return value of the signal function, and the
second operand is SIG_ERR, then it satisfies the constraint of
``both operands are pointers to qualified or unqualified versions
of compatible types'' (6.5.9 #2).

     Therefore your code fragment is correct.

Tak-Shing



Wed, 31 Mar 2004 18:28:14 GMT  
 Comparisons with value returned from "signal".


Quote:
>The standard library function "signal" has the following prototype:

>   void (* signal (int sig, void (* handler) (int))) (int);

>Hence, it returns a pointer to a function that takes an int and
>returns void.  Now, according to K&R2, the return value will
>be a pointer to the previous handler for the given signal, or
>SIG_ERR if an error occurs.  So presumably, it is intended that
>one be able to utilize it as follows:

>   old_handler = signal (sig, new_handler);
>   if (old_handler == SIG_ERR) {
>      /*  Deal with error.  */
>   }
>   /*  Continue, since signal handler  */
>   /*  registration succeeded.         */

>But I was under the impression that a pointer could only be
>compared to one of two things - (1) a pointer to an object
>in the same array that the first pointer points into, or

Or one place past the end of the array.

All of the above is true for the relational operators > >= < <=

Quote:
>(2) a null pointer (or a constant integral-type zero).

The equality operators == and != allow pointers to distinct objects (or
functions) to be compared and of course null pointers.

Quote:
>The value returned by "signal" is a pointer to a function,
>not a pointer to an object, so the first possibility is
>ruled out even if "signal" keeps all the signal handler
>pointers in a common array.  So does this mean that SIG_ERR
>is actually a null pointer, or is the comparison I showed
>above not legal, or do I misunderstand the rules on pointer
>comparisons?

SIG_ERR could be a pointer to a "dummy" function or something like
((void (*)(int))1) . This expression is not portable but an implementation
can use it in a standard header as long as it ensures that it works
on that implementation.

--
-----------------------------------------


-----------------------------------------



Wed, 31 Mar 2004 21:03:21 GMT  
 Comparisons with value returned from "signal".

Quote:

>   if (old_handler == SIG_ERR) ...
>The value returned by "signal" is a pointer to a function,
>not a pointer to an object, so the first possibility is
>ruled out even if "signal" keeps all the signal handler
>pointers in a common array.  So does this mean that SIG_ERR
>is actually a null pointer, or is the comparison I showed
>above not legal, or do I misunderstand the rules on pointer
>comparisons?

There are three "special" values for signal(), hidden behind macros
whose contents you are not supposed to inspect:

    SIG_DFL
    SIG_ERR
    SIG_IGN

At most one of these can be a null pointer.  In typical implementations
it is either SIG_DFL or SIG_IGN that is the null pointer (suitably
converted to void (*)(int) type).  Since it is the implementation
that gets to (and in fact has to) provide these macros, the
implementation can pick which -- if any -- is to be the null pointer,
and what implementation-specific trick to use for the other two.

Presumably the implementor -- the guy who writes the implementation
-- knows how to come up with three distinct values, all of which
work for pointer comparisons.  In the worst case (machines that
have complicated and scary hardware checking for valid pointers),
he might supply two or three routines inside the C library:

    void __sig_dfl(int dummy) {}
    void __sig_err(int dummy) {}
    void __sig_ign(int dummy) {}

and use their addresses, which are of course distinct from the
addresses of any user-supplied functions.  More often the implementor
can "cheat", because he is, after all, the same guy (or guys) as
those writing the C compiler(s), or is in cahoots with them.
--
In-Real-Life: Chris Torek, Wind River Systems (BSD engineering)




Thu, 01 Apr 2004 06:19:30 GMT  
 Comparisons with value returned from "signal".

Quote:
>The standard library function "signal" has the following prototype:

>   void (* signal (int sig, void (* handler) (int))) (int);

>Hence, it returns a pointer to a function that takes an int and
>returns void.  Now, according to K&R2, the return value will
>be a pointer to the previous handler for the given signal, or
>SIG_ERR if an error occurs.  So presumably, it is intended that
>one be able to utilize it as follows:

>   old_handler = signal (sig, new_handler);
>   if (old_handler == SIG_ERR) {
>      /*  Deal with error.  */
>   }
>   /*  Continue, since signal handler  */
>   /*  registration succeeded.         */

>But I was under the impression that a pointer could only be
>compared to one of two things - (1) a pointer to an object
>in the same array that the first pointer points into, or
>(2) a null pointer (or a constant integral-type zero).

This is wrong.  The equality operators can be used on any two pointers
to compatible types.  The relational operators are restricted to (1),
but they cannot be used for (2) at all.

Quote:
>The value returned by "signal" is a pointer to a function,
>not a pointer to an object, so the first possibility is
>ruled out even if "signal" keeps all the signal handler
>pointers in a common array.  So does this mean that SIG_ERR
>is actually a null pointer, or is the comparison I showed
>above not legal, or do I misunderstand the rules on pointer
>comparisons?

You have misunderstood the rules for the equality operators:

       6.5.9  Equality operators

       Syntax

       [#1]

               equality-expr:
                       relational-expr
                       equality-expr == relational-expr
                       equality-expr != relational-expr

       Constraints

       [#2] One of the following shall hold:

         -- both operands have arithmetic type;

         -- both  operands are pointers to qualified or unqualified
            versions of compatible types;

         -- one operand is a pointer to  an  object  or  incomplete
            type  and  the  other  is  a  pointer to a qualified or
            unqualified version of void; or

         -- one operand is a  pointer  and  the  other  is  a  null
            pointer constant.

SIG_ERR is, most likely, an integer constant cast to the appropriate
function pointer type, to keep the compiler happy.  For example, on the
system I'm typing this post, it is defined like this:

    #define SIG_ERR         (void (*)(int))-1

In principle, SIG_ERR could be a null pointer, but this wouldn't solve the
problem of the SIG_DFL and SIG_IGN macros, which have to be distinct from
SIG_ERR, but are still usable in the same way as SIG_ERR.

Dan
--
Dan Pop
CERN, IT Division

Mail:  CERN - IT, Bat. 31 1-014, CH-1211 Geneve 23, Switzerland



Mon, 05 Apr 2004 23:38:16 GMT  
 
 [ 6 post ] 

 Relevant Pages 

1. Q: Return-values of system("...") calls

2. Q : What is returned by "return;"

3. implementing "complete" comparison

4. catch "Abnomal Program Termination" signal

5. Send signal to "Com port", How?

6. implement a "kill" with signals

7. Raising "Invalid Property Values"

8. RegLoadKey returns "file not found".

9. "Faking" null in value types

10. Function without a "return type"?

11. Send integer value by "send( )"

12. syslog() returns "bad file number"

 

 
Powered by phpBB® Forum Software