[comp.lang.c] prototypes, NULL, and magic

throopw@sheol.UUCP (Wayne Throop) (03/24/91)

- torek@elf.ee.lbl.gov (Chris Torek)
- But alas, the new BSD man pages are going to continue to talk blithely
- about `NULL' as if the compiler worked magic.  Fortunately, in this case
- all the new man pages will say
-        #include <foo.h>
- and <foo.h> will contain all the necessary prototypes, so if you follow
- the man page, you will have a prototype in scope, and the compiler *will*
- work magic....

Remembering what Chief Dan George's character said about magic in Little
Big Man, I am moved to ask: what about the execl(2) family of functions,
or other like (varargs) cases? (Gosh, I hope this answer isn't in the
FAQ...  I don't recall it from my last reading anyway...)
--
Wayne Throop  ...!mcnc!dg-rtp!sheol!throopw

gwyn@smoke.brl.mil (Doug Gwyn) (03/27/91)

In article <1490@sheol.UUCP> throopw@sheol.UUCP (Wayne Throop) writes:
>... I am moved to ask: what about the execl(2) family of functions, ...

These are specified in IEEE Std 1003.1.  Yes, in general they might not
work right if invoked without a prototype in scope.  Note also that the
often-seen practice of using an unadorned "0" to terminate the execl()
list has always been incorrect; a null pointer of type char* is needed.

throopw@sheol.UUCP (Wayne Throop) (04/02/91)

- gwyn@smoke.brl.mil (Doug Gwyn)
-- throopw@sheol.UUCP (Wayne Throop)
-- ... I am moved to ask: what about the execl(2) family of functions, ...
- These are specified in IEEE Std 1003.1.  Yes, in general they might not
- work right if invoked without a prototype in scope.

While this is perfectly good information, it doesn't adequately address
the question I originally asked, for three reasons:

  - I was asking about the situation WITH a prototype in scope
  - I was asking about a specific environment, as well as in in general
    (perhaps this means I should have asked elsewhere, but my question
     was relevant to a general discussion that occured on comp.lang.c)
  - I was asking about the BSD 4.mumble implementation Chris Torek
    referenced, not about any relevant standards.

So, specifically: under the upcoming BSD release, with prototypes in
scope, is it really safe to use unadorned NULL to terminate a
variable argument list a-la execl(2) family as Chris seemed to
imply (but did not explicitly state)?  Or did I misunderstand?

More generally, with prototypes in scope, are there any but the default
promotions which occur for arguments referenced by the "..." argument
specifier?
--
Wayne Throop  ...!mcnc!dg-rtp!sheol!throopw

torek@elf.ee.lbl.gov (Chris Torek) (04/03/91)

In article <1561@sheol.UUCP> throopw@sheol.UUCP (Wayne Throop) writes:
>So, specifically: under the upcoming BSD release, with prototypes in
>scope, is it really safe to use unadorned NULL to terminate a
>variable argument list a-la execl(2) family as Chris seemed to
>imply (but did not explicitly state)?

Oh, is *that* what you meant?  Of course the answer is `no' ..

>More generally, with prototypes in scope, are there any but the default
>promotions which occur for arguments referenced by the "..." argument
>specifier?

... because the answer to this is (perforce) `no'.
-- 
In-Real-Life: Chris Torek, Lawrence Berkeley Lab CSE/EE (+1 415 486 5427)
Berkeley, CA		Domain:	torek@ee.lbl.gov

gwyn@smoke.brl.mil (Doug Gwyn) (04/03/91)

In article <1561@sheol.UUCP> throopw@sheol.UUCP (Wayne Throop) writes:
>So, specifically: under the upcoming BSD release, with prototypes in
>scope, is it really safe to use unadorned NULL to terminate a
>variable argument list a-la execl(2) family as Chris seemed to
>imply (but did not explicitly state)?  Or did I misunderstand?

No, that would depend on the implementation.  If NULL is defined as
0 (which is always allowed for a standard-conforming implementation),
there could easily be a problem.  The prototype does not specify the
types of the ,... arguments, so no automatic argument conversion
will be done for them.  If NULL is defined as ((void*)0), for
example, then it should work, only because void* and char* are
required to have the same representation (so if a char* is expected,
a void* can be passed for the actual argument).