Email List: Xaustin-review-lX
[All Lists]

Defect in XSH makecontext

To: yyyyyyyyyyyyyyy@xxxxxxxxxxxxx
Subject: Defect in XSH makecontext
From: yyyyyyy@xxxxxxx
Date: Fri, 14 Feb 2003 15:16:58 GMT
        Defect report from : Joanna Farley , Sun Microsystems

(Please direct followup comments direct to yyyyyyyyyyyyyy@xxxxxxxxxxxxx)

@ page 279 line 23931-23932 section makecontext objection {sunw-jf03-dc-1}

Problem:

Defect code :  1. Error

With the incorporation of ISO/IEC 9899:1999 (C99) into this
specification the makecontext() synopsis (XSH6, P279 L23931-23932) has
been modified to make it strictly C99 conforming.

The 1st paragraph of the description of makecontext() (XSH6, P729,
L23937-23940) says that the arguments following argc in the
makecontext() call are passed to func().  But, the "void (*func)(void)"
in the function prototype on XSH6, P729, L23931-23932 does not allow any
arguments to be passed to func(). Therefore, the standard conflicts with
itself except in the case when argc is zero.

In practice, func() is called by various applications with an arbitrary
number of arguments (including zero) of varying types. Specifying func()
as "void (*func)(int, ...)"  would break all existing applications that
currently use makecontext(), but it is the only way in ISO/IEC 9899:1999
(C99) to specify that func() takes one or more arguments of varying
types.  Furthermore, this would require that func() take at least one
argument (invalidating the example shown on XSH6, P729-730, L23957-23991).

C99 (subclause 6.11.6) specifies that the use of function declarators
with empty parentheses is an obsolescent feature. Therefore, using the
function prototype (as in XSH5, P493):

        void makecontext(ucontext_t *ucp, void (*func)(), int argc,...);

is making use of an obsolescent feature of C99.  Therefore, a strictly
conforming POSIX application can't use this form and is why it changed
in XSH6. 

There is no way in C99 to specify a non-obsolescent function prototype
indicating that a function will be called with an arbitrary number
(including zero) of arguments of arbitrary types (including integers,
pointers to data, pointers to functions, and composite types).

Therefore to continue to use the  
        void makecontext(ucontext_t *ucp, void (*func)(), int argc, ...);

form it needs to be marked obsolescent.

Replacing makecontext() with a bunch of C99 compatible functions handing
various numbers and types of arguments will force all existing uses of
makecontext() to be rewritten for little or no gain.  There are very few
applications today that use the *context() routines.  Those that do use
them are almost always using them to implement co-routines.  By going
back to the XSH5 specification for makecontext(), existing applications
will continue to work, although they won't be able to be classified as
strictly conforming applications.

We (standards developers) are stuck between a rock and a hard place
because there is no way in C99 (without using obsolescent behavior) to
specify functionality that was standard, strictly conforming behavior in
XSH5 using the 1990 C Standard.  Threads can be used to implement the
functionality provided by *context(), but is more complex to use.  We
believe that the pain of inventing new C99 compatible interfaces that
describe what can be done with the XSH5 functions and then converting
applications to use them would cause more pain than just converting
applications that use them to use threads instead.  (And, they can work
on this effort until the next revision of the POSIX standards is
approved.)



Action:

Change the makecontext() function prototype in XSH6 page 729 on lines
23931-23932 from:
        void makecontext(ucontext_t *ucp, void (*func)(void), int argc, ...);
    to:
        void makecontext(ucontext_t *ucp, void (*func)(), int argc, ...);

Mark getcontext() in XSH6 page 489, makecontext() in XSH6 page 729,
swapcontext() in XSH6 page 1460, and <ucontext.h> in XBD6 page 396
obsolescent.  

Add Application Usage in XSH6 page 730 at line 23993 and in XSH6 page
489 after line 16116 saying:

        "The obsolescent functions getcontext(), makecontext() and
swapcontext() can be replaced using POSIX threads functions."

Add rationale to makecontext() in XSH6 page 730 line 23995 saying:

"With the incorporation of ISO/IEC 9899:1999 (C99) into this
specification it was found that C99 (subclause 6.11.6) specifies that
the use of function declarators with empty parentheses is an obsolescent
feature. Therefore, using the function prototype:

        void makecontext(ucontext_t *ucp, void (*func)(), int argc, ...);

is making use of an obsolescent feature of C99.  Therefore, a strictly
conforming POSIX application can't use this form. Therefore, use of this
getcontext(), makecontext() and swapcontext() is marked obsolescent.

There is no way in C99 to specify a non-obsolescent function prototype
indicating that a function will be called with an arbitrary number
(including zero) of arguments of arbitrary types (including integers,
pointers to data, pointers to functions, and composite types).

Replacing makecontext() with a number of C99 compatible functions
handing various numbers and types of arguments would have force all
existing uses of makecontext() to be rewritten for little or no gain. 
There are very few applications today that use the *context() routines. 
Those that do use them are almost always using them to implement
co-routines.  By maintaining the XSH5 specification for makecontext(),
existing applications will continue to work, although they won't be able
to be classified as strictly conforming applications.

There is no way in C99 (without using obsolescent behavior) to specify
functionality that was standard, strictly conforming behavior in XSH5
using the 1990 C Standard.  Threads can be used to implement the
functionality provided by makecontext(), getcontext() and swapcontext()
but it is more complex to use.  It was felt inventing new C99 compatible
interfaces that describe what can be done with the XSH5 functions and
then converting applications to use them would cause more difficulty
than just converting applications that use them to use threads instead."

<Prev in Thread] Current Thread [Next in Thread>