WTF?

от автора

PVS-Studio, WTF?
Меня не покидает когнитивный диссонанс. На форумах обсуждаются возвышенные идеи о написании сверх надежных классов, кто-то рассказывает, что его проект собирается с ключами -Wall -Wextra -pedantic -Weffc++. Господи, где все эти достижения науки и техники? Почему я вижу кругом глупейшие ошибки? Может быть, со мной что-то не так?

Нет, на самом деле я вижу и отличные проекты. Примером может служить библиотека AGLIB. Это весьма интересная библиотека, с точки зрения кода. Пишется она на Паскале, а потом транслируется в C++, C#. Помимо прочих разных преимуществ, такой подход позволяет выловить много разных ошибок, так как одна и та же программа собирается компиляторами для разных языков. В прочем это отдельная история. Возможно, мы как ни будь, напишем с автором этой библиотеки совместную заметку.

Такие приятные исключения, пожалуй, ещё больше усиливают диссонанс. Вот представьте мои ощущения. Я беру сложный пакет численного анализа и не нахожу в нем ошибок. Мне радостно за качественный код. Немного только грустно, что такому человеку PVS-Studio не продать. Ну да ладно. Беру проект OpenCOLLADA. Проверяю. WTF? Других слов я подобрать не могу. Как вам такие конструкторы?

struct short2 {   short values[2];   short2(short s1, short s2)   {     values[0] = s1;     values[2] = s2;   }   .... };  struct double2 {   double values[2];   double2( double d1, double d2)   {     values[0]=d1;     values[0]=d2;   }   .... }

В первом конструкторе промахнулись мимо массива. Во втором скопировали строчку и забыли поменять индекс.

Прости читатель, не могу удержаться от картинки. Она очень точно передает мои эмоции.

WTF

«Доставляют» и другие конструкторы. Например, вот это мило:

struct ParserString : public UnionString {   ParserString()   {     UnionString::str = 0;     UnionString::length = 0;   }    ParserString(const int& val)   {     ParserString();   } };

Вместо вызова другого конструктора, создается и сказу уничтожается временный объект. А члены класса остаются неинициализированными. Подробнее.

Господи, где те люди, которые, засучив рукава, пишут статьи про C++11, лямбды, Boost.Asio, share_ptr, constexpr, LINQ. Почему я вижу в коде:

struct ObjectGroups{   componentList objectGrpCompList;   int objectGroupId;   short objectGrpColor;   void write(FILE* file) const; }* objectGroups;  void write(FILE* file) const {   size_t size = sizeof(objectGroups)/sizeof(ObjectGroups);   for(size_t i=0; i<size; ++i)   {     objectGroups[i].write(file);     if(i+1<size) fprintf(file," ");   } }

Поделили размер указателя на размер структуры и получили 0. Что вообще здесь хотели сделать? WTF?

Впрочем, когда даже понятно, что и как хотели записать в файл, от этого не легче.

void write(FILE* file) const {   fprintf(file,"%i %i %i %i ",     sDivisionCount, tDivisionCount, uDivisionCount, pointCount);   size_t size = pointCount*3;   for(size_t i; i<size; ++i)   {     fprintf(file, "%f", points[i]);     if(i+1<size) fprintf(file, " ");   } }

Если не заметили баг, то я подскажу. Переменная ‘i’ не инициализируется: for(size_t i; i<size; ++i).

Извините, что поделился всем этим с вами. Мне так легче. Заодно, я естественно скажу, что эти ошибки были найдены с помощью статического анализатора кода PVS-Studio. Расположение этих и некоторых других забавных ошибок я выложил вот в этом текстовом файлике. И как всегда, если будут желающие более тщательно проверить этот проект, я готов поделиться ключиком.

Удачи и безбажного вам кода!

ссылка на оригинал статьи http://habrahabr.ru/company/pvs-studio/blog/195928/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *