
Dear fellow programmers, I propose to share in the comments examples of errors that you think can be found in the program at the stage of its writing. Surely everyone had situations when correcting a bloop after an hour of debugging, you sighed "oh, so what did the compiler not give me a warning here?"
I am primarily interested in the patterns of errors made in C ++ programs. But I deliberately did not put this post in the "C ++" section. Give examples of errors from other languages. Often considering an error, you can come up with an analogue in another language.
I need errors to create a new, unique set of rules for diagnosing errors of a general type. Rules that are really relevant, which will find errors not in abstract applications, but in sensations given to us. It is not interesting to look for trigraphs that were randomly overlooked in the text. I have never seen an error related to the trigraph. But typos, where str.empty () is written to clean the string instead of str.clear (), is full. For example, I wrote about such an example
here . And because such errors are not existing tools! Therefore, we are following the path of creating the new, and not repeating the old.
')
Now I will try to clarify what kind of mistakes I want to hear and how.
I'll start with an example of the most banal typos.
double a;
a = 1.536;
Instead, the point is randomly written comma. As a result, this line is equivalent to "(a = 1), 536;" and the variable 'a' will take the value 1. The compiler will naturally keep silent (at least Visual C ++).
I am sure many people are already preparing a comment on the topic in their head that only a schoolboy can make such a mistake. In vain. No one is immune from such errors. This situation was described by one of the best programmers I know. This is
Dmitry Vyukov , holder of the title "Intel Programmer, Intel Black Belt". Author of many articles and project
Relacy Race Detector .
Here is his
message on the RSDN site about this very comma. Naturally, I could not help but pay attention to this post. The error is very real, relevant and can be detected by static analysis of the source code. Diagnostics of such errors was implemented by me in
PVS-Studio .
Let's go further. It is very easy to forget that std :: remove () does not remove elements, but only shifts them. And as a result, should be used in conjunction with erase () functions. Elena Sagalaeva (the author of the “Alena C ++” blog) made a good note about this: "
std :: remove and std :: remove_if don't actually delete anything ."
This is also a common, beautiful, up-to-date, high-level error. I like her very much. In a real application, it may look like this (ZThreads library):
void unregisterThread () {
Guard <TaskQueue> g (_taskQueue);
std :: remove (_threads.begin (), _threads.end (), ThreadImpl :: current ());
}
This fragment was found by PVS-Studio, after the implementation of the corresponding check created after reading Alena’s article.
I came up with the following rule myself, based on personal experience. It happened, and even now it happens that I make typos and use the wrong variable name. Some such errors can be detected automatically. For example, it is suspicious when one variable is assigned a different value. After the implementation of the corresponding diagnostics using PVS-Studio, we immediately discovered, for example, such an error in the Win32 ++ library:
class CSize: public SIZE
{
...
CSize (POINT pt) {cx = pt.x; cx = pt.y; }
I will give an example of another discussion, from which you can make a rule for static analysis. Here people could not understand for a long time that it is impossible to work with an array of derived classes through a pointer to the base class. And as is usually the case, they blamed the “buggy compiler”. In a discussion, the discussion of the delete operator can be confusing, so I’ll give my example:
class A
{
int a;
};
class B: public A
{
int b;
};
void FOO ()
{
B array [5];
A * p = array;
p [3] .a = 1; // We do not understand where to write
}
The size of classes A and B is different, and, therefore, array [i] and p [i] are addressed to different memory locations.
This is a very good example where static analysis can save a lot of nerve cells and time. The rule for diagnosing such errors in PVS-Studio has not yet been made, but it is written into the development plan.
I described various examples of how, based on discussions in forums, articles, personal experience, it is possible to make interesting rules for analysis. I will be glad if you share your examples or links to similar examples.
PS
If the opportunity to comment on the article is not available to you, then please write me on the karpov [@] viva64.com box or via the
contact form .