Hi,
Speaking as a newbie,
My opinion,
ASSERTS are eXtremely important when programming.
Every function has it's set of preconditions and postconditions
which you should state for yourself.
The good thing about this practice is that it changes your way of
thinking when programming the code. Because you have to rigorously
state what can be accepted and what not you are more focused as to
what can go wrong than what can go right about your code.
Just imagine yourself being a teacher who has to correct the
examinations of a 1000 students. Because of the amount of work to be
done, the most likely approach that you will do in correcting these
examinations is to look directly to the solution, skipping the student's
reasoning. Of course, you are not assured to be correcting 100%
correctly but it gets the job done within reasonable parameters.
So what the teacher actually did was just to check the postcondition
of every answer, with the mentality that when then answer is correct,
the reasoning must also be correct. (Again not a 100% correct
assumption)
An example, from my practical experience :
We had to implement a priorityqueue based on a heap.
We were allowed to use a STL container(like vector) to implement it.
So I have a
Code:
template<T>
class CHEAP {
public :.....
typedef vector<T> ContainerType;
private : ContainerType container;
};
I am almost obsessed with setting pre and postconditions, upto the
point I do like this :
Code:
template<T>
CHEAP::insert(in_el) {
1) ContainerType old(container);
/** --Contracts- Pre
* old == getContainer(), to make postcondition sane
*/
2) assert(old == getContainer());
/** --Contracten-- Post
* Assure that in_el is added.
* old != getContainer() makes sense thanks to precondition
* element_added(...) to assure this
*/
assert(old != getContainer());
assert(element_added(old, container, in_el));
};
element_added simple checks the contents of the 2 containers
and returns true if all the elements are identical except for in_el.
After I tested the class CHEAP, I decided to make an interface class
CPriorityQueue . Everything was working, but somehow, believe it or
not, but due to some stupid mistake (2) FAILED despite (1) being set.
This was contradictory to all logic, and wouldn't it have been for
that assert, I would had to spend hours in trying to find the relevant
bug.(because the bug is contradictory to logic...)
I realized very quickly that I did not call the methods of CHeap correctly
in CPriorityQueue. The compiler didn't give an error, which I think is
strange due to what I had done...
Whenever I make a program, I first make a design stating all pre and postconditions. Then I only implement the headings of this design.
I use vim to edit, and when I press F4 I get something like this
:MakeComment
I can input a parameter
:MakeComment +Foo(in_bar) : bool out_gnam {query}
When I press enter I get :
Code:
/* <------------------------- Foo(in_bar) : bool out_gnam {query} ------------------------------>
*
* PRECONDITIONS : -
* -
* POSTCONDITIONS : -
* -
*/
bool
CLASS::Foo(in_bar)
{
/* ----PRECONDITIONS-----
*/
Output("CLASS::Foo(in_bar)" );
/* ----POSTCONDITIONS----
*/
return out_gnam;
}
If you look on the web, Software Engineering Xtreme ASSERT you will probably find more information regarding this topic.
Regards.