Ben said:
What kind of code do you work on?
The code I am most familiar with where we have such debug routines is a
chunk of legacy code that does a fair amount of string manipulation on
items that are passed around in "instance" pointers that refer to files
and describe relationships to other files and pointers.
When I got here the debug routines were already in place. Basically we
have a debug module that we link in that has a run-time component. We
check for a few environment variables on startup, and based on that
enable 1-4 levels of debug() statements. If the variables are not set
the debug statements are turned into no-ops.
The debugging routines are implemented as varargs (I recall), so for
strings we know might be null we pass them through a "nulString()"
helper function that returns the pointer unmaligned, or the equivalent
replacement string that simply says "null" (or something).
For other issues, like pointers that might be freed before logging them,
this would be a bug in the code and a failure in the logger may as well
be caught ASAP.
It isn't perfect, and may in fact break some conventions or rules by
today's standards, but it was put in place literally decades ago.
Changing it now would introduce significant risk without giving us
something obvious in return. It is unlikely we are going to port this
library to any more platforms. It already runs nicely on a gaggle of
Unices and a long history of Windows stretching back to Win16. (Though
I'm sure it would break nicely on Win16 now).
Alas, the sun is sinking on this code as more and more is subsumed by
newer code written in Java.