How Programmers Spent 50 Hours Searching for One Small Error
Don't you just love going back and looking for bugs in your C++ code? Especially if you've copy-pasted somebody's code - or when that list of errors you've been looking through for hours turns out to have been prompted by a single typo. The human eye misses such mistakes in 80 cases out of 100. And there's no point in blaming the developer (please do show this text to your team lead!). The larger the project - the more likely the developer is to miss a bug or more significant problems like the following:
- buffer overflow;
- logical errors;
- dereferencing a null pointer, etc.
Even experienced developers miss these things. This is very easy to do. Detecting them in C++ code, on the other hand, is hard.
Want some examples?
Here's one. Wait to scroll the page down, take a look at the code. What do you think went wrong there?
if (ch >= 0x0FF00)
{
if (!((ch >= 0x0FF10) && (ch <= 0x0FF19)) ||
((ch >= 0x0FF21) && (ch <= 0x0FF3A)) ||
((ch >= 0x0FF41) && ((ch <= 0x0FF5A)))
{
if (j == 0)
continue;
ch = chx;
}
}
If you felt too lazy to look for bugs (what developer wouldn't!) - here's an explanation. Let's take a look at the condition again:
if (!((ch >= 0x0FF10) && (ch <= 0x0FF19)) ||
((ch >= 0x0FF21) && (ch <= 0x0FF3A)) ||
((ch >= 0x0FF41) && (ch <= 0x0FF5A)))
The developer wanted to make sure a character wasn't in either of the three ranges. However, the NOT (!) operator only applies to the first part of the expression.
So here's what the code actually does.
If the following condition is true:
!((ch >= 0x0FF10) && (ch <= 0x0FF19))
the short-circuit principle is applied and the rest of the expression is not evaluated.
If the condition is false, the ch variable lies in the following range: [0xFF10..0xFF19]. Thus, it makes no sense to check the variable against the next four parts of the expression. They will all be false or true:
ch >= 0x0FF21 — always false
ch <= 0x0FF3A — always true
ch >= 0x0FF41 — always false
ch <= 0x0FF5A — always true
Need more examples?
This is not the only case when a small bug becomes a big problem and takes away a lot of time and effort from developers. Looking for an error may take 50 hours and prove useless (true story!).
If you don't feel like reading the story, here's a summary: a developer spent 50 hours looking for an error, only to find and fix the error in under an hour thanks to a static analyzer.
What can you do?
You probably already understand that even experienced developers can make mistakes. And the worst part - in large projects, code belongs to all developers. So even if such mistakes are a no-brainer for you, there's no guarantee your coworker doesn't make one. And the resulting bug will be for everyone to catch and fix. Of course, static analysis can help you look for a hidden error before the release. But the main advantage static analysis gives companies is tracking dozens of common mistakes that somebody made by accident. Then and only then you will experience the full effect of such tools - and finally have time to focus on more important tasks than looking for bugs.
In order to make sure that your project is all right, you can use the 30-day trial version.