Por qué PVS-Studio no ofrece ediciones de código automáticas

Por qué PVS-Studio no ofrece ediciones de código automáticas


El analizador estático PVS-Studio detecta fragmentos de código bastante complejos y engañosos que contienen errores. Y cómo solucionarlos no siempre está claro incluso para una persona, y ahora consideraremos un par de ejemplos. Por lo tanto, es mejor no generar ninguna suposición sobre la corrección automática de código.



A veces, los programadores que comienzan a probar PVS-Studio se preguntan: ¿por qué la herramienta no ofrece corregir el error automáticamente? Curiosamente, los usuarios ya no hacen esta pregunta. Después de usar el analizador durante algún tiempo, se dan cuenta de que para la gran mayoría de los errores detectados, no es posible un reemplazo automático. Al menos hasta que se invente la inteligencia artificial.



La razón es que PVS-Studio no es un analizador de estilo de código. No sugiere cambios de formato o nombre. No sugiere (al menos en el momento de escribir este artículo :) reemplazar todos los NULL en el código C ++ con nullptr... Si bien esta es una buena sugerencia, casi no tiene nada que ver con la resolución de problemas.



PVS-Studio detecta errores y posibles vulnerabilidades. Muchos errores invitan a la reflexión y requieren un cambio en el comportamiento del programa. Y solo un programador puede decidir cómo solucionar este o aquel error.



Una vez encontrado un error, lo más probable es que el analizador sugiera simplificar el código para que desaparezca la anomalía, pero esto no solucionará el error en sí. Comprender lo que se supone que debe hacer el código y sugerir una solución útil y significativa es muy difícil.



Considere el error que analicé en el artículo " 31 de febrero ".



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];
  }
}


El analizador comprende que ambas pruebas son verdaderas. Pero por qué, el analizador no comprende. No sabe nada de días, meses y otras entidades. Y enseñar a entender tal oh, qué difícil es. Lo único que realmente se puede hacer es que el analizador sugiera simplificar la función:



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;
  }
}


O, qué podemos decir sobre las bagatelas, déjelo que ofrezca un reemplazo tan automático:



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;
}


Genial, pero inútil;). El analizador eliminó el código que es redundante desde el punto de vista del lenguaje C ++. Y solo una persona puede entender si el código es realmente redundante ( y esto también sucede a menudo ), o si hay un error tipográfico en el código y es necesario reemplazar el mes por el día .



El lector puede decir que estoy engrosando y el reemplazo automático es apropiado. No. La gente se equivoca en esto, ¿qué se puede pedir de un programa sin alma? Mira, hay un ejemplo interesante de edición manual desatendida que en realidad no soluciona nada. Dado que una persona no puede, tampoco un programa.



En agosto de este año viral, escribí un artículo.sobre la comprobación de la biblioteca PMDK. Entre otras cosas, el artículo consideró el error de protección contra desbordamiento incorrecta:



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;
}


Dado que rel_wait es de tipo unsigned, la verificación posterior de rel_wait <0 no tiene sentido. Advertencia de PVS-Studio: V547 [CWE-570] La expresión 'rel_wait <0' siempre es falsa. El valor del tipo sin firmar nunca es <0. os_thread_windows.c 359



Alguien se inspiró en el artículo y comenzó a corregir masivamente los errores descritos en él: Solucione varios problemas reportados por el análisis de PVS-Studio .



¿Y cómo se sugirió arreglar el código? Bastante simple: núcleo: simplifica la implementación del temporizador de Windows .



Corrección de código incorrecto


¡Pero el código fue simplificado, no arreglado! Esto se notó y comenzó una discusión correspondiente: PROBLEMA: os_thread_windows.c - get_rel_wait () bloqueará si abstime está en el pasado .



Como puede ver, incluso las personas cometen errores en las ediciones sugeridas. ¿Por qué probar los robots?



De todos modos, el deseo de corregir automáticamente los errores es un deseo muy extraño. Cada cambio que corrige un error requiere atención y revisión del código. Además, el analizador puede dar falsos positivos, lo que significa que no puede editar dicho código en absoluto. Analizar su código y lidiar con las advertencias no es el lugar para apresurarse. Es mejor implementar un análisis de código regular y corregir lentamente los errores que aparecen en el nuevo código.





Si desea compartir este artículo con una audiencia de habla inglesa, utilice el enlace de traducción: Andrey Karpov. Por qué PVS-Studio no ofrece soluciones automáticas .



All Articles