bugTired of encountering many bugs in your code? Well, that might be caused by your coding habits. Below are some tips on how to write code that is less error-prone than before!

1. Use assert macro

A good practice in designing a function or a block of code is to specify its preconditions. That specifies which variables must hold what values upon entering that block of code. A common example is the sqrt() function. The precondition is that its sole argument must be nonnegative.

There is a quick way to implement this idea. You can use assert macro from <cassert> header. Supply the predicate that you wish to assert as the argument. If the predicate evaluates to false/0, it will generate a pretty message to the standard error, and the program aborts. Example:

#include <cassert>
#include <cmath>

double safe_sqrt(double x)
{
    assert(x >= 0);
    return sqrt(x);
}

If you call safe_sqrt(-2), this line will be printed to the standard error:

double safe_sqrt(double): Assertion `x >= 0' failed.

But, remember, this asserting feature is not intended to be used in production program! It is for testing purposes only. So, if you wish to release your program, include this line

#define NDEBUG

before the inclusion of the <cassert> header. This will ignore all assert macros in your code.

2. Use consistent array indexing

This advice is important, especially for beginners. Many Pascal-to-C++ transitional programmers use 1-based indexing, while other expert C++ programmers prefer 0-based indexing. I don’t know which is better, but choose one style and stick with it! That will reduce bugs in your code, because many off-by-one errors are due to this issue.

3. Use loop macros

This technique is used extensively in TopCoder SRM by most programmers. Not only do it shortens the code a lot, but also eliminate some unexpected bugs, like wrong counter variables. How many times do you write something like this?

for (int j = 0; i < n; i++)

There are many style of loop macros. Some are standardly used by many coders. I recommend this style.

#define FOR(i, n) for (int i = 0, _n = (n); i < _n; i++)
#define FORD(i, n) for (int i = (n)-1; i >= 0; i--)
#define FORE(i, c) for (typeof((c).begin()) i = (c).begin(); i != (c).end(); ++i)

FOR is the usual for loop. FORD is FOR’s reverse, that is, iterating from n-1 to 0. FORE will iterate over a STL’s container.

4. Use STL

STL is the ultimate friend for C++ coders. It saves a lot of time coding by providing many basic algorithms, such as sorting,  and containers. Unless you’re doing high optimizations to your code, use STL whenever possible! You don’t have to worry because STL’s implementation has been heavily tested and is bug-free. Also it lets you think at higher level and you don’t have to screw its low-level implementations.

5. Use vector::at() instead of vector::operator[]

If for some reason you used vector rather than a plain array, you might consider this trick. Both methods do the same thing, i.e. returning the n-th element of the vector. But the former will throw an out_of_range exception if you request an element in a position that is out of range. That exception can be caught or properly handled in some ways, without aborting the program. Compare to operator[], that will crash the program!

OK, having read the tips above, now please practice at least one of this tips, and feel the difference, especially in contests!

  • Share/Bookmark

Enjoyed this article? Subscribe to our RSS feed for free!

Related posts:

Be the first to comment!

Leave a Reply