Re: fun with ?:

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, May 23, 2007 at 01:25:06AM +0100, Al Viro wrote:
> To clarify: all mess with null pointer constants comes from lack of
> explicit token and need to avoid massive breakage of old programs.  That's
> what it's all about - compiler recognizing some subexpressions as
> representations of that missing token and trying to do that in a way that
> would break as little as possible of existing C code.  It's an old story -
> decisions had to be made in 80s and now we are stuck with them.
> 
> IOW, (void *)0 in contexts that allow null pointer constant is *not* a
> 0 cast to pointer to void; it's a compiler-recognized kludge for __null__.
> And it's not a pointer to void.  It can become a pointer to any type,
> including void.  If converted to a pointer type it gives the same value
> you get if you convert 0 to that type ("null pointer to type").  But
> unlike null pointer to type it retains full flexibility.

PPS: original idiom for that sucker was, of course, simply 0.  My
understanding (and I'm seriously risking playing wrongbot here, so
take it with big grain of salt) is that raise of "cast 0 to pointer"
idiom was mostly due to targets where sizeof(pointer) > sizeof(int); there
the lack of prototypes meant that passing 0 in pointer argument would
do the wrong thing.  I _think_ it predates the introduction of void *, but
not by much; 32V source is available, so that would be a useful data point.
When use of void * stopped being serious portability issue it became the
best variant in that family (the most type-neutral of available options).
Then (void *)0 went into Feb 86 ANSI draft as acceptable alternative for null
pointer constant (i.e. recognized by compiler and converted to type
appropriate by context).

BTW, note that null pointer constant is *not* recognized in variable part
of argument list when you are calling a vararg function, so there you
get what you get - integer-type 0 or null pointer to void.  Which may
make life bloody interesting wrt portability.  Fortunately, these days
userland headers tend to have NULL defined to (void *)0 or integer 0
of the right size, so you are probably OK as long as you use
va_arg(..., void *) to get it, but $DEITY help you if you pass NULL
in vararg in place of pointer to function - on minimally weird targets
it will be ugly.  I don't think that sparse can catch that kind of
braindamage, though...
-
To unsubscribe from this list: send the line "unsubscribe linux-sparse" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Newbies FAQ]     [LKML]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Trinity Fuzzer Tool]

  Powered by Linux