Boost logo

Boost Users :

Subject: [Boost-users] Invariants (was: [boost] [review][constrained_value] Review of Constrained Value Library begins today)
From: Peter Simons (simons_at_[hidden])
Date: 2008-12-21 13:45:32


Hi Mika,

> No, I do not except [invariants] to fail. However, it is possible
> that they fail due to programming errors, and I would be naive to
> assume none would make it to release versions.

invariants as implemented by assert() have been around for decades and were
introduced into the C programming language by the likes of Brian Kernighan
and Dennis Ritchie. Since then, that functionality has been used in billions
of lines of code written by thousands of people from all over the world.
Personally, I would hesitate to take on a perspective that requires me to
believe that all those people are naive.

Say you write a function that performs some integer arithmetic and at some
point you call abs():

     int i = ... ;
     int j = std::abs(i);
     assert(j >= 0);

This is an invariant. There is NO WAY "j" is going to be less than zero,
right? Of course, your compiler might be broken or your standard library
might be broken or your CPU might be broken or your memory chips might be
broken, and that is why checking invariants is potentially beneficial during
software development. Another example is this one:

     T * ptr = new T;
     assert(ptr);

If "new" would fail, you'd get an exception, so clearly there is now way
"ptr" is going to be NULL, right?

So let's say "ptr" *is* NULL for some reason. What would you like to do
about it? How would you like to recover from such a fundamental problem? And
furthermore, would you like to perform that "ptr != 0" comparison in your
program every time you allocate an object? Would you like to compare "j >= 0"
every time you use std::abs()? What if that computation is performed inside
of loop that's being executed billions of times?

For debugging purposes, these checks might be useful, but in production code
these kind of checks are a waste of time.

Now, there is another kind of check:

  void * ptr = std::malloc(1024);
  if (ptr == 0) throw std::runtime_error("bad malloc");

To use an assert() at this point would be a mistake, because malloc() can
fail, and it will fail. The result "ptr == 0" is a perfectly valid state of
this program and not to consider this state would be a bug.

Take care,
Peter


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net