Wednesday, September 05, 2007

Assertions

[From] http://xmlrpc-c.sourceforge.net/doc/libxmlrpc.html

The concept of assertions in code is widely misunderstood, because it is somewhat more abstract than C coders are used to. An assertion is a statement in code that declares a certain fact to be true. It doesn't make it true; it just declares that the coder knows it is true. In a standard C library, the assert() function performs this duty.

But what does the statement cause the computer to do? If you're a high level coder, that's none of your business. You write code to describe the solution to a computational problem, and how the computer manipulates itself to compute the solution is beyond your concern. Your audience is the human reading your code.

So the most basic function of an assertion is to help the reader read the code. You assert that the value of variable foo is not zero, and that helps the reader see that it won't cause a problem to divide by it.

Another practical effect of an assertion could be that the compiler generates more efficient code with the additional information from your higher intelligence about how the program works. But I've never seen any actual compiler capable of that.

An assertion might also help the compiler to point out bugs in your program. You assert that the value of foo is zero, but you never initialized foo, so you obviously didn't write the program you thought you did. But I've never seen a compiler with that capability either.

Finally, there is run time checking of the assertion. This one is real. At run time, the program checks that the condition asserted really is true. If it isn't, which means the program is broken, it crashes itself. The advantages of this are twofold: 1) this makes it easier to diagnose the bug; 2) it stops the broken program from going on to damage something.

People often have trouble seeing the abstract meaning of an assertion and simply see it as a statement that tells the computer, "crash if X is not true." But in fact, it's quite the opposite: It says, "I assure you X is true."

People sometimes get the idea that assertion statements are for error checking. That is definitely not what they are for. If there is a possibility that X is false when the program is working as designed, you should not assert that X is true. Instead, check the truth of X and if it's false, issue an error message or exit the program or return with a failure return code, or something like that.

Incidentally, a common way you know something is true inside a subroutine is that you required as an entry condition to the subroutine that the caller make sure it is true. A subroutine assumes that it's entry conditions are met, so if you set up the requirement that the caller pass only positive values for parameter X, you may legitimately assert inside the subroutine that X is positive. In fact, that assertion is a good formal way to state that entry condition for the reader of the code.