Arthur J. O'Dwyer said:
I feel compelled to reiterate my opinion that
strcpy(s1, NULL)
really has no reasonable meaning.
No, but if the second argument is a variable (that may sometimes
be NULL), it does. The point is, often a char* variable has the
general semantic of "string or NULL" with NULL meaning "no string
YET assigned" or "string was optional" or like that. In such a
case, NULL == "" is not a far stretch, particularly when checking
length or copying.
(And what do you think of this one? UB again?)
strcpy(NULL, NULL)
That's why I said "const char*". You'd need to return NULL on
that one.
Aren't those two goals contradictory?
Imagine they aren't and go from there. (-:
If you want to bullet-proof your library code, then you do need
to check for NULLs and whatnot (thus effectively "troubleshooting"
whatever junk the client code throws at you).
Perhaps that is a side effect, but the check is to *protect* the
lib code from being able to invoke unknowable behavior.
I prefer not to troubleshoot the client's code, either. I think
that's the client's job. If he passes NULL to something that
doesn't expect NULL (and he knows it), then he's being foolish
and can troubleshoot his own dang code.
IME (which means both In My Experience and In My Environment), a
crash is *more* likely if you use the NULL than if you pretend it's
an empty string. The behavior of the system may be unexpected
(leading you to go troubleshooting), but (again, IME) that behavior
is preferrable to crashing (much of my code runs on production
lines that must not crash).
If I could be certain there were no bugs in the client code, it
wouldn't be a concern. But since that certainty is impossible,
I *must* (IMO) do what I can to prevent crashes. For me, that
means making a "best effort" with all data passed to me.
[Probably different meanings for the word "troubleshoot."
I'm using it in the sense of "fix the errors post-facto,"
as distinct from "prevent" ("stop errors from happening")
or "ignore" ("ignore").]
So am I. The opinion expressed when I had this debate previously
was that by using the NULL, you crash and alert the programmer to
the problem (allowing her to troubleshoot it). If I could be
100% certain this would always occur *during* development, then
I'd probably change my view.
Obviously I can't be 100% certain, so I try to make the library
code as crash-resistant as possible.