Richard said:
If you're not 100% sure that the program can run correctly without the
assertions, your program is not ready for production.
Corollary: No non-trivial program is ever ready for
production.
It seems to me that "ready for production" and "100%
bug-free" are not equivalent notions. A program is ready
for production when it is "good enough" for the application
at hand. A program may be "good enough" without being
"perfect" -- and certainly without satisfying the still
stronger condition of "proven perfect."
To put it another way: If unachievable perfection is the
criterion, the program will never be put into production.
The expected waiting time for the program to perform its
function is therefore infinite, and the ultimate result
(i.e., "nothing useful happens") can be achieved much more
quickly and cheaply by writing a program that crashes as
soon as it's invoked. In this sense, "100% bug-free" and
"100% bug-ridden" are operationally equivalent ;-)
Returning to the question of whether "production" code
should be built with or without NDEBUG defined, I seem to
recall PJ Plauger opining in "The Standard C Library" that
the problem with assert() in production code isn't that it
wastes cycles or some such, but that when it (inevitably)
*does* catch a problem the error message is gibberish to
the end user. It would seem to follow (although I don't
recall whether Plauger said so explicitly) that production
code should in fact test for its own correct operation, but
should use some nicer mechanism than the developer-oriented
bare assert().
There's also the experience some years back of the little
robot that landed on Mars, crawled around doing stuff, and
kept mysteriously freezing up and rebooting. The problem (a
classic priority inversion) was fixed only because the on-Mars
software (a "production" deployment if I've ever heard of one!)
still had its debugging probes activated; this facilitated
Earth-side analysis and provided a vehicle for uploading what
amounted to a patch. Looking back on the incident, a senior
software person on the project gave it as a mantra: "Test what
you fly, and fly what you test" -- in short, if you test the
code with debug probes in place, pulling out the probes leaves
you with a program that has seen *no* testing at all! Put the
former, not the latter, into production.