Static analysis tools have advanced far over the time they've been around. They no longer resemble the "linters" that were in active use 20 years ago. But some programmers still view them as extremely primitive tools. And that's very sad. It hurts to see the static analysis methodology in general and our PVS-Studio analyzer in particular treated that way.


That feeling was evoked by a comment left under one of our articles. In that article, we said that the analyzer would detect a typo by issuing a warning on the following code pattern:

if (A[0] == 0)
{
  X = Y;
  if (A[0] == 0)
    ....
}

The analyzer says the second condition is always true. Indeed, a close look at the function's body reveals that the programmer intended some other element to be checked.

Now, someone commented on this along the following lines:
Yes, it's indeed an error in this particular case. But in the general case, this warning is wrong because the element may change its value during the time between the two identical checks, in which case the second check would make sense.
It's sad. Programmers still seem to think that code analyzers are based on the use of regular expressions – they believe the tool gets mad on simply seeing two identical nested ifs :(.

Of course, any modern static analyzer tracks the changes of variables' values. If a variable doesn't change, a warning is issued. If it does, no warning is issued. To ensure that, analyzers rely on data stream analysis.

And that's exactly how PVS-Studio works. Let's take a look at the following synthetic example:

char get();
int foo(char *p, bool arg)
{
    if (p[1] == 1)
    {
        if (arg)
            p[0] = get();
        if (p[1] == 1)          // Warning
            return 1;
    }
    if (p[2] == 2)
    {
        if (arg)
            p[2] = get();
        if (p[2] == 2)          // Ok
            return 2;
    }
    return 3;
}

This code consists of two similar blocks. In one, the variable being checked doesn't change, while in the other it does. That's why the analyzer issues a warning only on the first block: V547 Expression 'p[1] == 1' is always true.

Programmers needn't worry. Modern tools are advanced enough to issue warnings only on really suspicious code. Sure, false positives occur every now and then, but they usually have to do with complicated code structure, which even a human reviewer may have a hard time figuring out.


Further reading

Комментарии (0)