On Sat, Jul 15, 2006 at 08:42:29PM -0700, Andy Spitzer wrote:
> I think that passing NULL to formatting functions for %s should not
> crash, (ala glibc) as NULL is a perfectly legal value for a string.
> It is the same as passing the results of 1.0 /0.0 to a %f. The
> formating functions convert that to "Inf", why shouldn't they
> convert NULL %s as "(NULL)" as well?
Your analogy is flawed. NaN is a well-defined, valid floating-point
non-quantity. If you were to take the address of such a value, the
resulting pointer would likewise be valid, and dereferencing it would
yield the expected result. Instead, the analog to NaN is the empty
string (""), which contains nothing yet has a valid, well-defined
address which can be dereferenced. NULL isn't a pointer to anything,
and is therefore not an acceptable argument to a function which
requires a pointer to *something*. To complete your analogy in the
converse, passing NULL to a function which expects a float * is no
more acceptable than passing NULL to a function which expects a char
*, even if the former would happily accept a pointer to NaN.
> Formatting a NULL %s shouldn't cause a crash. Dereferencing a NULL
> pointer should. For those who argue program correctness, most likly
> a program that prints a NULL string will then try to use it later,
> and it will crash then. Seeing the "(NULL)" printed in the output
> would help with the fix.
printf() has every right to dereference its arguments. It is the
caller's responsibility to provide valid pointers. NULL is not a
valid pointer; the behaviour of dereferencing it may vary from
platform to platform, but an attempt to format a string value for
display and dereferencing the pointer to that string are
indistinguishable and should have the same result. On most systems,
that result is SEGV.
Also, if you change printf(), shouldn't you likewise change fprintf(),
sprintf(), vfprintf(), snprintf(), vprintf(), vsnprintf(), and perhaps
even puts()? After all, changing only printf would be extremely
confusing, and probably wrong since printf(...) is defined to be
equivalent to fprintf(stdout,...). What about the string-handling
functions? And gets() and fgets(). And what about sprintf();
shouldn't it check its buffer too? For that matter, why not check the
format strings as well while we're at it? I could go on and on. The
fact is, it's not a nerf universe. If you want your pointers tested
for NULL, test them. It's not the library's job to validate your
arguments beyond what the standards require. If the standard doesn't
say you can pass the function a NULL pointer, it's your responsibility
to see to it that you don't. If you do it anyway, the best thing for
the library to do is the straightforward thing, and in most cases that
means doing whatever it would have done with the pointer had it been
valid. It helps no one to delay a crash until later, when the
corruption may have spread or even been made persistent, and detecting
the original cause of the error will be difficult or even impossible.
It doesn't matter whether this is development or production, either;
the consequences may be different, but in neither case is driving on a
desirable choice for the library to make.
As a trivial example, suppose a printf-family function were being used
to write to disk a record which ought to contain a string exactly 10
bytes long. Unfortunately, a programming error has resulted in a NULL
pointer instead, and the function happily writes out "(null)". While
one would hope the code responsible for later reading this file will
be resilient against this type of corruption, it would be much better
to have crashed immediately rather than write invalid data. A
counterargument, of course, would be that the return from printf
should be checked in this case, and indeed it should. But printf
shouldn't be doing the unexpected, especially where your data's
concerned. After all, printf is not (only) a debugging function, all
the more reason to use your own wrapper to check for NULL and perform
any other debugging-specific deviations from the standards that you
may require.
--
Keith M Wesolowski "Sir, we're surrounded!"
Solaris Kernel Team "Excellent; we can attack in any direction!"
_______________________________________________
opensolaris-code mailing list
[email protected]
http://mail.opensolaris.org/mailman/listinfo/opensolaris-code