From man 3 assert_perror
:
The purpose of the assert macros is to help programmers find bugs in their programs, things that cannot happen unless there was a coding mistake. However, with system or library calls the situation is rather different, and error returns can happen, and will happen, and should be tested for. Not by an assert, where the test goes away when NDEBUG is defined, but by proper error handling code. Never use this macro.
I find it hard to understand the above rationale.
Granted, it is kind of obvious for some error codes. For example, according to man 2 recv
, this function can fail with EINTR
when “the receive was interrupted by delivery of a signal before any data were available”. For certain, the use of assert
or assert_perror
to test against this error code in most cases seems to be an exceptionally bad idea.
However, recv()
can also fail with EFAULT
if “the receive buffer pointer(s) point outside the process's address space”. Such a situation clearly “cannot happen unless there was a coding mistake”, and thus the primary purpose of testing against this error seems to be “to help programmers find bugs in their programs”. Despite whatever man 3 assert_perror
says, I cannot see how the situation of recv()
failing with EFAULT
can be “rather different” from any other bug that can be tested against with an assert()
macro.
Granted, in such a case, just as with any other situation when a clear bug has been detected at runtime, the program should probably stop. But this is also true for any other bug. If we bring up that argument against the use of assert_perror
in such a situation, we automatically condemn the use of assert()
for any non-computation-heavy test in favor of running this test at runtime and terminating the program should this test fail.
Why should we never use the assert_perror
macro or test against library functions failing with certain error codes with the assert
macro?