[comp.lang.c] Abandon NULL for

ian@ux.cs.man.ac.uk (Ian Cottam) (09/20/89)

Here is a C style suggestion that I am about to adopt (for you to
throw bricks at).  It is related to the issue of silly-little-macros,
but I have decided to use it after following discussions on the net
regarding implementations and users (!) that (re-)define NULL to
something stupid.  The original motivation for writing NULL rather
than 0 was, IMHO, to help the reader of a program text spot where the
denotation 0 meant ``the null pointer''.  I propose that the
integral constant expression

				(0)
be used instead of NULL.

Some example code:

/*
 * Initialise a new stack variable; return false iff init attempt fails
 */
bool
initstack(Stack *s)
{
	extern void *malloc(unsigned int);
	StackHeaderPtr tmp= (StackHeaderPtr)malloc(sizeof(StackHeader));

	if ( (0) == tmp )
		return false; /* malloc failed -- no store */
	else {
		tmp->top= (0); 	/* set stack empty */
		tmp->reserve= (StackElemPtr)malloc(sizeof(StackElem));
		if ( (0) == tmp->reserve )
			return false; /* malloc failure */
		else {
			*s= (Stack)tmp;
			return true;
		}
	}
}


-----------------------------------------------------------------
Ian Cottam, Room IT101, Department of Computer Science,
University of Manchester, Oxford Road, Manchester, M13 9PL, U.K.
Tel: (+44) 61-275 6157         FAX: (+44) 61-275-6280
ARPA: ian%cs.man.ac.uk@nss.cs.ucl.ac.uk   
JANET: ian@uk.ac.man.cs    UUCP: ..!mcvax!ukc!mur7!ian
-----------------------------------------------------------------

tneff@bfmny0.UU.NET (Tom Neff) (09/22/89)

In article <6502@ux.cs.man.ac.uk> ian@ux.cs.man.ac.uk (Ian Cottam) writes:
> I propose that the integral constant expression (0) be used instead of
> NULL.

However (0) is not explicitly cast to a pointer type, as NULL may be
presumed to be when appropriate.  For instance if I refer to, but do not
declare or define, an external routine that accepts a single pointer as
its argument, by saying myproc((0)), the compiler will Miranda it into a
regular int, rather that ((void *) 0), which might have a different size
and representation.
-- 
"UNIX should be used          ::   Tom Neff <tneff@bfmny0.UU.NET> or
 as an adjective." -- AT&T   ::    ...uunet!bfmny0!tneff (UUCP only)

chad@csd4.csd.uwm.edu (D. Chadwick Gibbons) (09/22/89)

In article <14718@bfmny0.UU.NET> tneff@bfmny0.UU.NET (Tom Neff) writes:
|In article <6502@ux.cs.man.ac.uk> ian@ux.cs.man.ac.uk (Ian Cottam) writes:
|> I propose that the integral constant expression (0) be used instead of
|> NULL.
|
|However (0) is not explicitly cast to a pointer type, as NULL may be
|presumed to be when appropriate.

	So?  When 0 used in a comparison with a pointer, it is automatically
promoted to an integer pointer of an appropriate type.

|declare or define, an external routine that accepts a single pointer as
|its argument, by saying myproc((0)), the compiler will Miranda it into a
|regular int, rather that ((void *) 0), which might have a different size
|and representation.

	yeah, talk about assuming sizeof * = sizeof int. Nononono!

If you're really parinoid about using NULL, because your compiler may do
something like the above person is suggestion, then try this:

#define NIL	(0)

simple, no?

gwyn@smoke.BRL.MIL (Doug Gwyn) (09/22/89)

In article <14718@bfmny0.UU.NET> tneff@bfmny0.UU.NET (Tom Neff) writes:
>However (0) is not explicitly cast to a pointer type, as NULL may be
>presumed to be when appropriate.

No, it may NOT be so presumed.

>For instance if I refer to, but do not declare or define, an external
>routine that accepts a single pointer as its argument, by saying
>myproc((0)), the compiler will Miranda it into a regular int, rather
>that ((void *) 0), which might have a different size and representation.

And also a different representation from the (struct foo *) that was
expected.

Passing NULL to a function (assuming no prototype in scope) without
casting it to the correct pointer type is a BUG.

scott@bbxsda.UUCP (Scott Amspoker) (09/22/89)

In article <14718@bfmny0.UU.NET> tneff@bfmny0.UU.NET (Tom Neff) writes:
>In article <6502@ux.cs.man.ac.uk> ian@ux.cs.man.ac.uk (Ian Cottam) writes:
>> I propose that the integral constant expression (0) be used instead of
>> NULL.
>
>However (0) is not explicitly cast to a pointer type, as NULL may be
>presumed to be when appropriate.  For instance if I refer to, but do not
>declare or define, an external routine that accepts a single pointer as
>its argument, by saying myproc((0)), the compiler will Miranda it into a
>regular int, rather that ((void *) 0), which might have a different size
>and representation.

Good point.  Professionally, I cast everything - makes lint real happy.
At home I use 0 for a null pointer.  I test pointers with expressions
like:
       if (pointer)...			/* at home */
       if (!pointer)...

as opposed to

       if (pointer!=(char *)0)		/* at work */

Modern C compilers are quite reliable about this - but you have
to watch out with those function calls.  However, function prototyping
solves that problem.  In fact, function prototyping has saved my
butt on many occasions.  Too bad it is not yet common enough to use
professionally.

-- 
Scott Amspoker
Basis International, Albuquerque, NM
(505) 345-5232

jas@postgres.uucp (James Shankland) (09/22/89)

In article <146@bbxsda.UUCP> scott@bbxsda.UUCP (Scott Amspoker) writes:
>Professionally, I cast everything - makes lint real happy.

Actually, in most cases, lint couldn't care less.  It is a fallacy that
the degree of portability of your code varies directly with the number
of casts in it.  Casts are conversions whose semantics are, in many
cases, implementation-dependent.

>At home I use 0 for a null pointer.  I test pointers with expressions
>like:
>       if (pointer)...			/* at home */
>       if (!pointer)...

Stylistically a little dubious, in my opinion, but certainly widely
practiced.  Also entirely safe.

>as opposed to
>
>       if (pointer!=(char *)0)		/* at work */
>
>Modern C compilers are quite reliable about this ...

Modern C compilers will reliably generate warnings on this if `pointer'
has any type other than `char *'.  Modern C compilers will be
entirely happy if you leave out the cast, provided `pointer' is any
scalar or pointer type.

jas

karl@haddock.ima.isc.com (Karl Heuer) (09/22/89)

Some people have been raising the strawman that "(0)" is inferior to "NULL"
because of an implicit cast which they believe to be attached to the latter.

This is not true.  In C, *any* use of "NULL" in a portable context (namely,
anyplace where a null pointer constant of some type was intended, except for
an uncasted argument to a function not covered by a prototype%) may be safely
replaced with "(0)".  Hence, this is no reason to avoid using "(0)".

Despite which, there *are* good reasons for not doing it.  The word "NULL" has
been conventionally used for decades to represent a null pointer constant;
when I see it, I know that it's a pointer context.  The original poster seemed
to be recommending the use of redundant parens around the zero to convey this
same information, which would be okay except that it's not an established
convention already.  People will look at it and scratch their heads.

In particular, if I were maintaining that code, I'd change the "(0)"'s back to
"NULL"'s as fast as I found them.  And if NULL were misimplemented on that
implementation, I'd simply fix that problem, rather than pollute my own code
with a workaround.

Karl W. Z. Heuer (ima!haddock!karl or karl@haddock.isc.com), The Walking Lint
________
% In which case neither "NULL" nor "0" is portable; you need a cast.

scott@bbxsda.UUCP (Scott Amspoker) (09/22/89)

In article <17505@pasteur.Berkeley.EDU> jas@postgres.berkeley.edu (Jim Shankland) writes:

 >>At home I use 0 for a null pointer.  I test pointers with expressions
 >>like:
 >>       if (pointer)...			/* at home */
 >>       if (!pointer)...
 >
 >Stylistically a little dubious, in my opinion, but certainly widely
                 ^^^^^^^^^^^^^^
I guess that's where personal preference comes in.  I consider it
a lot easier to read that way (and to type in :-).

 >>as opposed to
 >>
 >>       if (pointer!=(char *)0)		/* at work */
 >>
 >Modern C compilers will reliably generate warnings on this if `pointer'
 >has any type other than `char *'.

Sorry I wasn't clear on this.  It was simply a general example.  Of
course I would use the appropriate pointer type in the cast.

-- 
Scott Amspoker
Basis International, Albuquerque, NM
(505) 345-5232

henry@utzoo.uucp (Henry Spencer) (09/23/89)

In article <14718@bfmny0.UU.NET> tneff@bfmny0.UU.NET (Tom Neff) writes:
>However (0) is not explicitly cast to a pointer type, as NULL may be
>presumed to be when appropriate...

Sigh.  WRONG.  You cannot presume that the two will differ in behavior,
because one of the two possible definitions for NULL is `0'.  In all
contexts except arguments to a function, either form will get converted
automatically.  In that context, it depends on whether you have an ANSI
function prototype visible at the time.  If yes, both forms will be
converted.  If no, neither will be converted.

>For instance if I refer to, but do not
>declare or define, an external routine that accepts a single pointer as
>its argument, by saying myproc((0)), the compiler will Miranda it into a
>regular int, rather that ((void *) 0), which might have a different size
>and representation.

Which is true but quite irrelevant, since there is no guarantee at all
that the size and representation of `(void *) 0' will be right for some
arbitrary pointer type.  (There is a guarantee that it will be right for
`char *', but that does not generalize to, say, `int *'.)
-- 
"Where is D.D. Harriman now,   |     Henry Spencer at U of Toronto Zoology
when we really *need* him?"    | uunet!attcan!utzoo!henry henry@zoo.toronto.edu

djones@megatest.UUCP (Dave Jones) (09/23/89)

From article <14718@bfmny0.UU.NET>, by tneff@bfmny0.UU.NET (Tom Neff):
> In article <6502@ux.cs.man.ac.uk> ian@ux.cs.man.ac.uk (Ian Cottam) writes:
>> I propose that the integral constant expression (0) be used instead of
>> NULL.
> 
> However (0) is not explicitly cast to a pointer type, as NULL may be
> presumed to be when appropriate.

Presume all you want, but that won't cast it. I cut this directly
out of Sun-3's stdio.h:

#define NULL    0

It's the same in BSD-4.2.  NULL is turned into 0 by the preprocessor
before the compiler proper ever sees it. NULL is an SLM (silly little
macro) that means 0.

This topic comes up in this group every now and then. After all the arguing
is over -- and it can take months -- the survivers come to the conclusion
that NULL is a mistake, but it's too late to correct it. Just say,
(FILE*)0, or (char*)0, or whatever.

kim@kim.misemi (Kim Letkeman) (09/23/89)

In article <14678@haddock.ima.isc.com> karl@haddock.ima.isc.com (Karl Heuer) writes:
>Despite which, there *are* good reasons for not doing it.  
>The word "NULL" has been conventionally used for decades 
>[...]
>In particular, if I were maintaining that code, I'd change the "(0)"'s 
>back to "NULL"'s as fast as I found them. 
>[...]

Finally, someone has addressed the most important issue with that
posting ... the fact that using "(0)" instead of "NULL" makes the
program harder to read and maintain. There are enough brackets (and
braces and ellipses) in the average program without adding more as a
superfluous replacement for a good convention. I also did not like the
original author's tendency to write the NULL first in a comparison
(e.g. if (NULL == some_ptr)) because this obscures the fact that the
pointer is the object of interest. The value for which you are
comparing is secondary (although important.)

-- 
Kim Letkeman    uunet!mitel!spock!kim

karl_auer_%7801.801@fidogate.fido.oz (1) (09/27/89)

Original to: karl@haddock.ima.isc.com
In a message to All <22 Sep 89 15:42:26>, karl@haddock.ima.isc.com wrote:
 > In particular, if I were maintaining that code, I'd change the "(0)"'s 
 > back to "NULL"'s as fast as I found them.

There is another good reason not to use '(0)' - in some
implementations of C, pointers can have different sizes, requiring
that NULL be sometimes defined as (0), sometimes as (0L) - as with
almost all 80n86 implementations! Having a #define called NULL allows
the program cc (or equivalent) to pick the appropriate include files,
or allows conditional #defines depending on memory model (the usual
method).

Besides, I prefer a meaningful word to a meaningless constant number
any day!

Regards, K.

--- Qtach2 v1.04 U4
 * Origin: Aust. QNX Users Group (+61-62-514589 9am-5pm AEST) (3:7801/801)

scm@datlog.co.uk ( Steve Mawer ) (10/03/89)

In article <1005@kim.misemi> kim@kim.misemi (Kim Letkeman) writes:
> [stuff about using "(0)" instead of "NULL" making programs harder to
> read and maintain]
>                                               I also did not like the
>original author's tendency to write the NULL first in a comparison
>(e.g. if (NULL == some_ptr)) because this obscures the fact that the
>pointer is the object of interest. The value for which you are
>comparing is secondary (although important.)

I also find this comparison ordering unpleasant, but (silver lining!) 
it is a convenient way of finding those irritating moments when you've
mistyped "==" as "=".

-- 
Steve C. Mawer        <scm@datlog.co.uk> or < {backbone}!ukc!datlog!scm >
                       Voice:  +44 1 863 0383 (x2153)

jpr@dasys1.UUCP (Jean-Pierre Radley) (10/04/89)

In article <8241@goofy.megatest.UUCP> djones@megatest.UUCP (Dave Jones) writes:
>This topic comes up in this group every now and then. After all the arguing
>is over -- and it can take months -- the survivers come to the conclusion
>that NULL is a mistake, but it's too late to correct it. Just say,
>(FILE*)0, or (char*)0, or whatever.

I have found my code to more readable if I use these two defines:

#define	NULLC (char *)0
#define NULLF (FILE *)0

-- 
Jean-Pierre Radley					      jpr@jpradley.uucp
New York, NY					      72160.1341@compuserve.com

diamond@csl.sony.co.jp (Norman Diamond) (10/05/89)

In article <10839@dasys1.UUCP> jpr@dasys1.UUCP (Jean-Pierre Radley) writes:

>I have found my code to more readable if I use these two defines:
>
>#define	NULLC (char *)0

This one doesn't look so readable to me.  NULLC very clearly means the
character that comes at the end of a string.

Why not try:

  #define  NULLC  '\0'
  #define  NULLS  (char *) 0

(This gives NULLC the exact same definition that NULL should have, but
so what.  The proper use of NULLC helps provide self-documenting code.)

>#define NULLF (FILE *)0

Mixed feelings about this one.  Its name is reminiscent of /dev/null
(and similar pseudo-files on other operating systems).  There is a
difference between a file opened to /dev/null and an unopened file.

-- 
Norman Diamond, Sony Corp. (diamond%ws.sony.junet@uunet.uu.net seems to work)
  The above opinions are inherited by your machine's init process (pid 1),
  after being disowned and orphaned.  However, if you see this at Waterloo or
  Anterior, then their administrators must have approved of these opinions.

daveh@marob.masa.com (Dave Hammond) (10/05/89)

In article <10839@dasys1.UUCP> jpr@dasys1.UUCP (Jean-Pierre Radley) writes:
>I have found my code to more readable if I use these two defines:
>
>#define	NULLC (char *)0
>#define NULLF (FILE *)0
>

For the vast majority of data types, a single macro can produce
a properly cast null pointer:

#define NIL(t)	(t *)0

This produces fairly readable and maintainable code, as in:

fp = fopen("foo","r");
if (fp == NIL(FILE))
	{ ... }

The only pathological case which I define a separate macro for is
null pointer-to-function:

#define NILFUNC(t)	(t (*)())0

--
Dave Hammond
daveh@marob.masa.com

wen-king@cit-vax.Caltech.Edu (King Su) (10/06/89)

In article <15571@nswitgould.cs.uts.oz> karl_auer_%7801.801@fidogate.fido.oz (1) writes:
>Original to: karl@haddock.ima.isc.com
<There is another good reason not to use '(0)' - in some
>implementations of C, pointers can have different sizes, requiring
>that NULL be sometimes defined as (0), sometimes as (0L) - as with
<almost all 80n86 implementations! Having a #define called NULL allows
>the program cc (or equivalent) to pick the appropriate include files,
<or allows conditional #defines depending on memory model (the usual
>method).

Please be sure to add that this is not required if a program is
correctly written, and it is merely a fixe to get some incorrectly
written programs to compile.
-- 
/*------------------------------------------------------------------------*\
| Wen-King Su  wen-king@vlsi.caltech.edu  Caltech Corp of Cosmic Engineers |
\*------------------------------------------------------------------------*/

chris@mimsy.UUCP (Chris Torek) (10/06/89)

In article <252B5E41.1244@marob.masa.com> daveh@marob.masa.com (Dave Hammond)
writes:
[`#define NIL(t) (t *)0' works for most types]
>The only pathological case which I define a separate macro for is
>null pointer-to-function:
>
>#define NILFUNC(t)	(t (*)())0

Note that in Classic C, this is a `pointer to function returning t',
but in New C, this is a `pointer to function of unknown arguments
returning t' and that the latter type is Officially Frowned Upon.
One is supposed to write monstrosities like

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

Then a nil pointer (which, incidentally, is not as an action defined
for signal(), although SIG_DFL is usually a nil pointer) of the
appropriate type can be made with

	#define	SIG_DFL	((void (*)(int)) 0)

It all gets a bit clearer with typedefs:

	typedef void (*pointer_to_signal_function)(int);
	pointer_to_signal_function signal(int, pointer_to_signal_function);
	#define	SIG_DFL	((pointer_to_signal_function) 0)

(except, of course, that implementors are not allowed to use the name
`pointer_to_signal_function'---you are more likely to see something like
the original, or like

	typedef void (*__sfp_t)(int);
	__sfp_t signal(int, __sfp_t);
	#define SIG_DFL ((__sfp_t) 0)

in your <signal.h>).
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris@cs.umd.edu	Path:	uunet!mimsy!chris

chris@mimsy.UUCP (Chris Torek) (10/06/89)

In article <15571@nswitgould.cs.uts.oz> karl_auer_%7801.801@fidogate.fido.oz
(1) writes:
>There is another good reason not to use '(0)' - in some
>implementations of C, pointers can have different sizes, requiring
>that NULL be sometimes defined as (0), sometimes as (0L) - as with
>almost all 80n86 implementations!

No, sorry; the above statement is false.  The antecedent is correct
---in many systems, pointers of different types have different sizes
or formats.  However, `0' is always a correct and proper source code
representation for the generic nil pointer, which must be converted
immediately into a specific nil pointer by cast, assignment, comparison,
or by being an argument to a function that has a prototype in scope.
(The first and last are both special cases of assignment.)

>Having a #define called NULL allows ... conditional #defines depending
>on memory model (the usual method).

IBM PC compiler vendors do this only because they are interested in
having incorrect source code compile to correct binary code, without
any work on the part of the user.

(It should not be surprising that it is possible to make correct
binaries from incorrect sources.  For instance, the following
program works on a VAX:

	short main[] = { 0, 0x50d4, 4 };

This is a very machine-specific implementation of /bin/true.)

The incorrect source code in question is usually of the form

	void f() { g(NULL); }
	void g(p) char *p; { if (p == NULL) printf("hello\n"); }

This code can be fixed in one of two ways: provide a prototype for
g(), or apply a cast:

	void g(char *);
	void f() { g(NULL); }

or

	void f() { g((char *)NULL); }

Other, equivalent source code representations for this program can
also be devised (including using 0, (0), 0L, (1-1), etc. instead of
NULL).
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris@cs.umd.edu	Path:	uunet!mimsy!chris

henry@utzoo.uucp (Henry Spencer) (10/06/89)

In article <252B5E41.1244@marob.masa.com> daveh@marob.masa.com (Dave Hammond) writes:
>#define NIL(t)	(t *)0
>
>This produces fairly readable and maintainable code, as in:
>
>if (fp == NIL(FILE))

Is there some reason why this is superior to `if (fp == (FILE *)NULL)' or
just `if (fp == NULL)'?  You don't need that cast anywhere except in an
argument to a function (in the absence of ANSI C prototypes).
-- 
Nature is blind; Man is merely |     Henry Spencer at U of Toronto Zoology
shortsighted (and improving).  | uunet!attcan!utzoo!henry henry@zoo.toronto.edu

henry@utzoo.uucp (Henry Spencer) (10/06/89)

In article <15571@nswitgould.cs.uts.oz> karl_auer_%7801.801@fidogate.fido.oz (1) writes:
>There is another good reason not to use '(0)' - in some
>implementations of C, pointers can have different sizes, requiring
>that NULL be sometimes defined as (0), sometimes as (0L)...

Such implementations are broken.  In standard C it is *always* legal to
use `0' (the parentheses are unnecessary) anywhere where you could use
NULL.  Of course, it is also necessary to cast those NULLs to the correct
type when passing them as arguments to functions.  (The 0L nonsense is an
attempt, only partially successful, to cater to amateur programmers who
don't bother with this.)
-- 
Nature is blind; Man is merely |     Henry Spencer at U of Toronto Zoology
shortsighted (and improving).  | uunet!attcan!utzoo!henry henry@zoo.toronto.edu

gwyn@smoke.BRL.MIL (Doug Gwyn) (10/07/89)

In article <15571@nswitgould.cs.uts.oz> karl_auer_%7801.801@fidogate.fido.oz (1) writes:
>or allows conditional #defines depending on memory model

	#define NULL 0
is correct for all memory models and for all C implementations.
Sometimes other definitions are also correct, but the above is universal.

rcd@ico.ISC.COM (Dick Dunn) (10/07/89)

karl_auer_%7801.801@fidogate.fido.oz writes:

> There is another good reason not to use '(0)' - in some
> implementations of C, pointers can have different sizes, requiring
> that NULL be sometimes defined as (0), sometimes as (0L) - as with
> almost all 80n86 implementations!...

We seem to have to go through this rather frequently, but:

NULL should never need to be defined as 0L.  The compiler is required to
treat 0 in a pointer assignment or comparison as a null pointer, period.
Whatever conversions or adjustments are required MUST be done transpar-
ently or the compiler is broken, period.

The one case the compiler will not handle (in pre-function-prototype C) is
calling a function with a null pointer as an actual parameter.  In this
case a cast is required--NOT a lengthening of the pointer, but a cast to
the appropriate type.  In this case it's the responsibility of the program,
and if the program doesn't do it, it's broken.

80386 C implementations don't have a problem because (unless the implemen-
tor was stupid or lazy), ints and pointers are 32 bits.  80n86, n<3, need
not have a problem.  Some implementations do, but they're broken.
-- 
+---------+     Dick Dunn    rcd@ico.isc.com    ico!rcd      (303)449-2870
| In this |         4th annual MadHatterDay [10/6/89]:
|  style  |               Madness takes its toll
|__10/6___|

djones@megatest.UUCP (Dave Jones) (10/07/89)

From article <15571@nswitgould.cs.uts.oz>, by karl_auer_%7801.801@fidogate.fido.oz (1):

> There is another good reason not to use '(0)' - in some
> implementations of C, pointers can have different sizes ...


Aaaaarrrrggggghh!!!!  Will this never cease?

On many (most? all?) Unixes, NULL has nothing at all to do with pointers.

Zip.

Nada.

Zilch.

It is just a silly little macro which means 0. Look it up. It happens
to reside in the stdio.h header-file, probably because somebody or
another back in antiquity thought that was a cute way to say "0".

Usually the compiler will figure out that you need a pointer, and
explicitly cast the zero to a pointer type. But you must 
always cast the 0 (a.k.a NULL) to a pointer explicitly in function
parameter lists, unless you have ANSII prototypes, and there is one
in scope. Even then I would cast it explicitly, for safety -- the
prototype might get dropped or changed -- and for clarity.

Say,

      (void*)0

or

      (char*)0

or
      (caddr_t)0

or
      (FILE*)0

or whatever.

ok@cs.mu.oz.au (Richard O'Keefe) (10/07/89)

In article <16178@vail.ICO.ISC.COM>, rcd@ico.ISC.COM (Dick Dunn) writes:
> NULL should never need to be defined as 0L.

Right on!  _Please_ don't do that; there _are_ machines with 64-bit
"long"s and 32-bit pointers, you know.  [Well, at least one, anyway.]

pt@geovision.uucp (Paul Tomblin) (10/10/89)

In article <19999@mimsy.UUCP> chris@mimsy.UUCP (Chris Torek) writes:
>One is supposed to write monstrosities like
>
>	void (*signal(int, void (*)(int)))(int);
>
For some strange reason, our VMS C compiler has the following in signal.h:

int (*signal (int sig, void (*func)(int, ...)) ) (int, ...);

which seems slightly contradictory.  Since our code doesn't use prototypes
yet, or signals in the VMS code,  I haven't been able to investigate whether
this is going to cause some sort of compiler warning every time the code
trys to capture the old signal handler, set up a new one, and restore the
old one after the signal has been handled.

Someone care to comment on why Dec did it this way, and if they are planning
to fix it later?
-- 
Paul Tomblin,  Feeping Creaturism Section, DeptRedncyDept | ADA was invented 
    UUCP:   nrcaer!cognos!geovision!pt ??                 | because  Vogon 
    Disclaimer: The opinions expressed here aren't        | Poetry wasn't
    necessarily even mine!                                | deadly enough.

gwyn@smoke.BRL.MIL (Doug Gwyn) (10/12/89)

In article <740@geovision.UUCP> pt@geovision.UUCP (Paul Tomblin) writes:
>For some strange reason, our VMS C compiler has the following in signal.h:
>int (*signal (int sig, void (*func)(int, ...)) ) (int, ...);
>Someone care to comment on why Dec did it this way, and if they are planning
>to fix it later?

They were probably following BSD's lead.  BSD UNIX at one point started
passing additional information to signal handlers for certain classes of
signals (e.g. FPE exceptions).  This is horribly nonportable, as is
treating fixed-argument functions the same as variadic functions.

Anyway, it's wrong.  The standard signal() function's signal handlers
are NOT variadic; they receive precisely one int argument.

henry@utzoo.uucp (Henry Spencer) (10/13/89)

In article <10898@riks.csl.sony.co.jp> diamond@riks. (Norman Diamond) writes:
>>#define NULLF (FILE *)0
>
>Mixed feelings about this one...

Besides, what good is it?  One very seldom has to pass a null FILE pointer
to a function -- none of the stdio functions, the primary customers for
FILE pointers, accept one -- and that's the only place where the cast is
needed.  `if (f == NULL)' strikes me as no less readable than the equivalent
with NULLF, and it means exactly the same thing.
-- 
A bit of tolerance is worth a  |     Henry Spencer at U of Toronto Zoology
megabyte of flaming.           | uunet!attcan!utzoo!henry henry@zoo.toronto.edu