Warum PVS-Studio keine automatischen Code-Änderungen anbietet

Warum PVS-Studio keine automatischen Code-Änderungen anbietet


Der statische Analysator PVS-Studio erkennt ziemlich komplexe und knifflige Codefragmente, die Fehler enthalten. Und wie man sie behebt, ist selbst einer Person nicht immer klar, und jetzt werden wir einige Beispiele betrachten. Daher ist es am besten, überhaupt keine Annahmen über die automatische Code-Korrektur zu generieren.



Manchmal fragen Programmierer, die PVS-Studio ausprobieren , warum das Tool nicht anbietet, den Fehler automatisch zu beheben. Interessanterweise stellen Benutzer diese Frage nicht mehr. Nach längerer Verwendung des Analysators stellen sie fest, dass für die überwiegende Mehrheit der erkannten Fehler kein automatischer Austausch möglich ist. Zumindest bis die künstliche Intelligenz erfunden ist.



Der Grund dafür ist, dass PVS-Studio kein Codestil-Analysator ist. Es werden keine Formatierungs- oder Namensänderungen vorgeschlagen. Er schlägt nicht vor (zumindest zum Zeitpunkt dieses Schreibens :), alle NULL-Werte im C ++ - Code durch nullptr zu ersetzen... Dies ist zwar ein guter Vorschlag, hat jedoch fast nichts mit der Fehlerbehebung zu tun.



PVS-Studio erkennt Fehler und potenzielle Schwachstellen. Viele Fehler regen zum Nachdenken an und erfordern eine Änderung des Programmverhaltens. Und nur ein Programmierer kann entscheiden, wie dieser oder jener Fehler behoben werden soll.



Nachdem ein Fehler gefunden wurde, schlägt der Analysator höchstwahrscheinlich vor, den Code so zu vereinfachen, dass die Anomalie verschwindet. Dadurch wird der Fehler jedoch nicht selbst behoben. Es ist sehr schwierig zu verstehen, was der Code eigentlich tun soll, und eine sinnvolle, hilfreiche Lösung vorzuschlagen.



Betrachten Sie den Fehler, den ich im Artikel " 31. Februar " analysiert habe .



static const int kDaysInMonth[13] = {
  0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
};

bool ValidateDateTime(const DateTime& time) {
  if (time.year < 1 || time.year > 9999 ||
      time.month < 1 || time.month > 12 ||
      time.day < 1 || time.day > 31 ||
      time.hour < 0 || time.hour > 23 ||
      time.minute < 0 || time.minute > 59 ||
      time.second < 0 || time.second > 59) {
    return false;
  }
  if (time.month == 2 && IsLeapYear(time.year)) {
    return time.month <= kDaysInMonth[time.month] + 1;
  } else {
    return time.month <= kDaysInMonth[time.month];
  }
}


Der Analysator versteht, dass beide Tests wahr sind. Aber warum, versteht der Analysator nicht. Er weiß nichts über Tage, Monate und andere Wesenheiten. Und zu lehren, so oh zu verstehen, wie schwierig es ist. Das einzige, was wirklich getan werden kann, ist, dass der Analysator vorschlägt, die Funktion zu vereinfachen:



bool ValidateDateTime(const DateTime& time) {
  if (time.year < 1 || time.year > 9999 ||
      time.month < 1 || time.month > 12 ||
      time.day < 1 || time.day > 31 ||
      time.hour < 0 || time.hour > 23 ||
      time.minute < 0 || time.minute > 59 ||
      time.second < 0 || time.second > 59) {
    return false;
  }
  if (time.month == 2 && IsLeapYear(time.year)) {
    return true;
  } else {
    return true;
  }
}


Oder, was können wir zu Kleinigkeiten sagen, lassen Sie ihn einen solchen automatischen Ersatz anbieten:



bool ValidateDateTime(const DateTime& time) {
  if (time.year < 1 || time.year > 9999 ||
      time.month < 1 || time.month > 12 ||
      time.day < 1 || time.day > 31 ||
      time.hour < 0 || time.hour > 23 ||
      time.minute < 0 || time.minute > 59 ||
      time.second < 0 || time.second > 59) {
    return false;
  }
  return true;
}


Cool, aber sinnlos;). Der Analysator hat den aus Sicht der C ++ - Sprache überflüssigen Code entfernt. Und nur eine Person kann verstehen, ob der Code wirklich redundant ist ( und dies passiert auch häufig ) oder ob der Code einen Tippfehler enthält und der Monat durch den Tag ersetzt werden muss .



Der Leser kann sagen, dass ich verdicke und ein automatischer Austausch angebracht ist. Nein. Die Leute irren sich darin, was kann man von einem seelenlosen Programm erwarten? Schauen Sie, es gibt ein interessantes Beispiel für unaufmerksame manuelle Bearbeitung, die eigentlich nichts behebt. Da eine Person nicht kann, kann auch kein Programm.



Im August dieses viralen Jahres schrieb ich einen ArtikelInformationen zum Überprüfen der PMDK-Bibliothek. In dem Artikel wurde unter anderem der Fehler eines falschen Überlaufschutzes berücksichtigt:



static DWORD
get_rel_wait(const struct timespec *abstime)
{
  struct __timeb64 t;
  _ftime64_s(&t);
  time_t now_ms = t.time * 1000 + t.millitm;
  time_t ms = (time_t)(abstime->tv_sec * 1000 +
    abstime->tv_nsec / 1000000);

  DWORD rel_wait = (DWORD)(ms - now_ms);

  return rel_wait < 0 ? 0 : rel_wait;
}


Da rel_wait vom Typ ohne Vorzeichen ist, ist die nachfolgende Prüfung auf rel_wait <0 bedeutungslos. PVS-Studio-Warnung: V547 [CWE-570] Der Ausdruck 'rel_wait <0' ist immer falsch. Der vorzeichenlose Typwert ist niemals <0. Os_thread_windows.c 359



Jemand war von dem Artikel inspiriert und begann, die darin beschriebenen Fehler massiv zu beheben: Beheben Sie verschiedene Probleme, die von der PVS-Studio-Analyse gemeldet wurden .



Und wie wurde vorgeschlagen, den Code zu reparieren? Ziemlich einfach: Kern: Vereinfachen Sie die Implementierung des Windows-Timers .



Fehlerhafte Codekorrektur


Aber der Code wurde vereinfacht, nicht behoben! Dies wurde bemerkt und eine entsprechende Diskussion begann: AUSGABE: os_thread_windows.c - get_rel_wait () wird blockiert, wenn die Abstinenz in der Vergangenheit liegt .



Wie Sie sehen können, machen sogar Leute Fehler bei den vorgeschlagenen Änderungen. Wo können Roboter es versuchen?



Wie auch immer, der Wunsch, Fehler automatisch zu korrigieren, ist ein sehr seltsamer Wunsch. Jede Änderung, die einen Fehler behebt, erfordert Aufmerksamkeit und Codeüberprüfung. Darüber hinaus kann der Analysator falsch positive Ergebnisse generieren, was bedeutet, dass Sie diesen Code überhaupt nicht bearbeiten können. Das Analysieren Ihres Codes und der Umgang mit Warnungen ist nicht der richtige Ort, um sich zu beeilen. Es ist besser, eine regelmäßige Code-Analyse zu implementieren und Fehler, die in neuem Code auftreten, langsam zu beheben.





Wenn Sie diesen Artikel einem englischsprachigen Publikum zugänglich machen möchten, verwenden Sie bitte den Übersetzungslink: Andrey Karpov. Warum PVS-Studio keine automatischen Korrekturen anbietet .



All Articles