KholdCode

Very rarely, a case comes up where a new function is required even if it is functionally identical to another one. In these cases another meaning is attached to these functions beyond their interface, and machine instructions; reusing it will actually be counterproductive. We examine such a case I encountered at my workplace.

Assertions

I’m sure you’re wondering what the heck I’m talking about- reuse is a
cornerstone of programming! Well, consider the case of assertions. Peppered
throughout the codebase of a project, are macro invocations to
FOO_ASSERT, which is defined thus:

The assert macro provides information on the failure, including a message, and
all is good. It also allows one to disable the assertion if required, during
compilation. If we consider the interface and functionality of this macro, it
achieves the following:

Check a condition COND

On failure:

Print a nice MESSAGE

Exit the program

Handling errors

As it turns out, given the above functionality, the macro started being used
in smaller applications to do regular error handling.

FILE*file=fopen("somefile.txt","r");FOO_ASSERT(file!=NULL,"Could not open file!");

The macro simplified handling errors such as opening files, while inadvertently
corrupting its original meaning:

Assertions check invariants which have to hold during normal program
execution. If a condition is not satisfied, the logic of the program
broken.

Failing to open a file is not an invariant, and is not under the program’s
control. The FOO_ASSERT macro is being abused to handle regular
errors, and as a consequence, disabling assertions would now break these
applications- the check has to be there to preserve functionality.

After doing some profiling on the algorithms used, more than 50% of the time was
spent checking (legitimate) assertions. Without being able to remove their
usage, the code is stuck with the assertions. Granted, speed/efficiency was not
a requirement, but that is a lot of wasted cycles simply due to the misuse of a
macro.

Conclusion

Handling assertions and regular errors are fundamentally different, even if
functionally they are the same from the perspective of the source code. This
suggests that the usage/semantics of a construct is not only tied to its
functionality, but also to its documentation and project coding style.