Pour obtenir une clé
d'essai remplissez le formulaire ci-dessous
Demandez des tariffs
Nouvelle licence
Renouvellement de licence
--Sélectionnez la devise--
USD
EUR
RUB
* En cliquant sur ce bouton, vous acceptez notre politique de confidentialité

Free PVS-Studio license for Microsoft MVP specialists
To get the licence for your open-source project, please fill out this form
** En cliquant sur ce bouton, vous acceptez notre politique de confidentialité.

I am interested to try it on the platforms:
** En cliquant sur ce bouton, vous acceptez notre politique de confidentialité.

Votre message a été envoyé.

Nous vous répondrons à


Si vous n'avez toujours pas reçu de réponse, vérifiez votre dossier
Spam/Junk et cliquez sur le bouton "Not Spam".
De cette façon, vous ne manquerez la réponse de notre équipe.

>
>
>
Why code reviews are good, but not enou…

Why code reviews are good, but not enough

23 Sep 2020
Author:

Code reviews are definitely necessary and useful. It's a way to impart knowledge, educate, control a task, improve code quality and formatting, fix bugs. Moreover, you can notice high-level errors related to the architecture and algorithms used. So it's a must-have practice, except that people get tired quickly. Therefore, static analysis perfectly complements reviews and helps to detect a variety of inconspicuous errors and typos. Let's look at a decent example on this topic.

0761_Why_Code_Reviews_Are_Good_But_Not_Enough/image1.png

Try to find an error in the code of a function taken from the structopt library:

static inline bool is_valid_number(const std::string &input) {
  if (is_binary_notation(input) ||
      is_hex_notation(input) ||
      is_octal_notation(input)) {
    return true;
  }

  if (input.empty()) {
    return false;
  }

  std::size_t i = 0, j = input.length() - 1;

  // Handling whitespaces
  while (i < input.length() && input[i] == ' ')
    i++;
  while (input[j] == ' ')
    j--;

  if (i > j)
    return false;

  // if string is of length 1 and the only
  // character is not a digit
  if (i == j && !(input[i] >= '0' && input[i] <= '9'))
    return false;

  // If the 1st char is not '+', '-', '.' or digit
  if (input[i] != '.' && input[i] != '+' && input[i] != '-' &&
      !(input[i] >= '0' && input[i] <= '9'))
    return false;

  // To check if a '.' or 'e' is found in given
  // string. We use this flag to make sure that
  // either of them appear only once.
  bool dot_or_exp = false;

  for (; i <= j; i++) {
    // If any of the char does not belong to
    // {digit, +, -, ., e}
    if (input[i] != 'e' && input[i] != '.' &&
        input[i] != '+' && input[i] != '-' &&
        !(input[i] >= '0' && input[i] <= '9'))
      return false;

    if (input[i] == '.') {
      // checks if the char 'e' has already
      // occurred before '.' If yes, return false;.
      if (dot_or_exp == true)
        return false;

      // If '.' is the last character.
      if (i + 1 > input.length())
        return false;

      // if '.' is not followed by a digit.
      if (!(input[i + 1] >= '0' && input[i + 1] <= '9'))
        return false;
    }

    else if (input[i] == 'e') {
      // set dot_or_exp = 1 when e is encountered.
      dot_or_exp = true;

      // if there is no digit before 'e'.
      if (!(input[i - 1] >= '0' && input[i - 1] <= '9'))
        return false;

      // If 'e' is the last Character
      if (i + 1 > input.length())
        return false;

      // if e is not followed either by
      // '+', '-' or a digit
      if (input[i + 1] != '+' && input[i + 1] != '-' &&
          (input[i + 1] >= '0' && input[i] <= '9'))
        return false;
    }
  }

  /* If the string skips all above cases, then
  it is numeric*/
  return true;
}

To avoid accidentally reading the answer right away, I'll add a picture.

0761_Why_Code_Reviews_Are_Good_But_Not_Enough/image2.png

I don't know if you found the error or not. Even if you found it, I'm sure you'll agree that it's not easy to find such a typo. Moreover, you knew that there was an error in the function. If you hadn't known, it would have been hard to make you read and check all this code carefully.

In such cases, a static code analyzer will perfectly complement the classic code review. The analyzer doesn't get tired and will thoroughly check all the code. As a result, the PVS-Studio analyzer notices an anomaly in this function and issues a warning:

V560 A part of conditional expression is always false: input[i] <= '9'. structopt.hpp 1870

For those who didn't notice the error, I will give an explanation. Here's the main part:

else if (input[i] == 'e') {
  ....
  if (input[i + 1] != '+' && input[i + 1] != '-' &&
      (input[i + 1] >= '0' && input[i] <= '9'))
      return false;
}

The above condition checks that the i-th element is the letter 'e'. Accordingly, the following check input[i] <= '9' doesn't make sense. The result of the second check is always false, which is what the static analysis tool warns you about. The reason for the error is simple: the person was hasty and made a typo, forgetting to write +1.

In fact, it turns out that the function doesn't check the correctness of the entered numbers as expected. Correct version:

else if (input[i] == 'e') {
  ....
  if (input[i + 1] != '+' && input[i + 1] != '-' &&
      (input[i + 1] >= '0' && input[i + 1] <= '9'))
      return false;
}

Here's an interesting fact. This error can be considered as a kind of the "last line effect" one. An error was made in the last condition of the function. By the end of this snippet, the programmer's attention weakened, and they made this barely noticeable mistake.

GetFreeTrialImage

If you like the article about the last line effect, I recommend reading about other similar ideas: 0-1-2, memset, comparisons.

Bye everyone. Kudos to those who found the bug themselves.

Popular related articles
Intermodular analysis of C and C++ projects in detail. Part 2

Date: 14 Jul 2022

Author: Oleg Lisiy

In part 1 we discussed the basics of C and C++ projects compiling. We also talked over linking and optimizations. In part 2 we are going to delve deeper into intermodular analysis and discuss its ano…
Intermodular analysis of C and C++ projects in detail. Part 1

Date: 08 Jul 2022

Author: Oleg Lisiy

Starting from PVS-Studio 7.14, the C and C++ analyzer has been supporting intermodular analysis. In this two-part article, we'll describe how similar mechanisms are arranged in compilers and reveal s…
How to speed up building and analyzing of your project with Incredibuild?

Date: 17 Mai 2021

Author: Maxim Zvyagintsev

"How much longer are you going to build it?" - a phrase that every developer has uttered at least once in the middle of the night. Yes, a build can be long and there is no escaping it. One does not s…
GTK: the first analyzer run in figures

Date: 04 Jan 2021

Author: Svyatoslav Razmyslov

For some people, the introduction of a static analyzer into a project seems like an insurmountable obstacle. It is widely believed that the amount of analysis results issued after the first run is so…
Did it have to take so long to find a bug?

Date: 21 Déc 2020

Author: Svyatoslav Razmyslov

Have you ever wondered which type of project demonstrates higher code quality – open-source or proprietary? Our blog posts may seem to suggest that bugs tend to concentrate in open-source projects. B…

Comments (0)

Next comments
Unicorn with delicious cookie
Nous utilisons des cookies pour améliorer votre expérience de navigation. En savoir plus
Accepter