Is it bad practice to use them?
If abused, yes, particularly assert
.
One abuse is depending on those assert
statements to be active. You should never depend on assert
to do anything because the code can be compiled with NDEBUG
defined and then assert
does nothing. Production code is oftentimes compiled with NDEBUG
defined to ensure that those assert
statements disappear.
Unless you are writing a one-off program that won't live for more than a day or two, you shouldn't use to validate user input. Users don't care where the code failed, and the message that is printed looks like a foreign language to many users. It doesn't tell the user how to fix the error. It's also very unforgiving, by design. The message issued in response to a user input error should be a message that tells the user how to fix the problem. The best action after the message is to offer the user a way to fix the error. If that can't be done, and if the only viable response is to end the program, the program should terminate cleanly. By design, assert
does not result in a clean shutdown. It calls abort()
rather than exit()
.
One consequence of abort()
on many machines is to produce a core dump. A core dump is a great error message for a programmer. With a core dump, a programmer can use the debugger to see what went wrong in great detail. A downside of abort()
is that things aren't cleaned up. Abort "terminates the program without executing destructors for objects of automatic or static storage duration and without calling the functions passed to atexit()
."
Bottom line: It's okay (and good) to use assert
to test for programming errors, but only in a non-production setting. Use something else to test for user errors.