Обновить

Комментарии 49

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

Вот, видимо, на статьи вся творческая энергия и уходит, а в реальной жизни сроки, поддержка унаследованных подсистем, разные платформы, лень…
Еще короткие спринты и указания лида «надо чтоб работало, а не блестело».
В чем преимущество PVS над IDE от Jetbrains?
Вы имеете ввиду их новую разработку для C++?
«В чем преимущество статического анализатора кода над средой разработки?»
Я о говорил о статическом анализаторе у них в IDE, который подобные косяки также распознает.
У них Clang. Соответственно это вопрос сравнения с Clang на который коллега отвечал ниже.
Ммм… Тем что они решают совершенно разные задачи? А так же тем, что JetBrains еще не умеют C++?
Гораздо.
После «В прочем» и «как ни будь» читать дальше не смог…
Исправил. Такие вещи принято отписывать в личных сообщениях.
Не убоимся гнева народного, но в данном случае хочется сказать "WTF? Нас не покидает когнитивный диссонанс".
Авторы редкой хорошей программы по проверке правильности написанного кода — уверены в необходимости своей программы, проверяют программы написанные на «компьютерных» языках, публично в это тыкают, при этом дивясь на глупые ошибки допущенные другими и не исправленные после проверки…
… а сами же, в своем собственном пиар-блоге, не только пишут с ошибками, но и плюют на включение проверки ошибок в банальном русском языке при написании статьи, да еще и выговаривают за публичное указание на их ошибки.

Не это ли ответ на Ваш "WTF? Нас не покидает когнитивный диссонанс". Сами-то почему так делаете?
Это кстати не наезд:) Это реально интересный вопрос. Почему вы, авторы программы для проверки ошибок, хорошей надо сказать программы, не считаете нужным пользоваться программами для проверки ошибок? Возможно здесь скрыта сермяжная правда.
Я допускаю ошибки. Признаю это. Все допускают. Будьте снисходительны.
Да, в этой статье получилось много опечаток. Слишком эмоционально писал.
То что ошибки допускают все — это самоочевидно и снисходительность тут не при чем, т.к. это нормальное явление. Вопрос был абсолютно в другом.

Вопрос в том, почему вы — будучи автором программы для проверки ошибок, т.е. видимо осознавая нужность проверки ошибок — сами свои тексты на ошибки не считаете нужным проверять. Ошибки-то указанные не грамматические, не какие-то сложные, а именно те, на которые любая проверялка как на красную тряпку реагирует.
Еще раз — это абсолютно не наезд на вас. Это реально интересный вопрос из серии «почему сапожник без сапог».
Вероятно, они пытались напускать статический анализатор на статьи, но ничего не получилось.
НЛО прилетело и опубликовало эту надпись здесь
Это уже б-м понятно, что код — отстой, а PVS Studio — клевый продукт. ;) Но было бы интересно прочесть статью/цикл статей о том, как запилить свой анализатор кода на коленке. Понятное дело, что никто не требует раскрывать свои ноухау, но хоть примерные наброски было бы намного интересней читать, чем статьи — от которых пахнет маркетингом за версту — с перечислением ошибок в продуктах.
Стараемся. Например здесь мы написали как мы делали наш плагин.
Начинайте писать компилятор, а как дойдет до миддла, сконцентрируйтесь на статическом анализе. Вот и получится свой анализатор. Ну, а как писать компилятор уже написано миллион книжек и статей.
Со временем я попробую написать такую статью. Но боюсь, она получится далеко не такой интересной, как ожидается. Разработка ядра анализатора состоит из двух основных частей. Подготовки инфраструктуры для сбора данных и реализация диагностических правил. В первом случае, разумно было бы писать про Clang, так как это самый персептивный вариант создания дополнительных диагностик. Но я в нем не разбираюсь. Писать же про то, что сделано у нас на базе старого OpenC++ не очень кому-то полезно. Также, на мой взгляд, нет ничего интересного как там в какие массивы как и что собирается. Так что остается вторая часть — правила.

Но и тут не очень понятно, что интересного написать. Каждое правило существует (в основном) само по себе. Пишутся они так. Берется идея. Например «подозрительно, если после for стоит сразу точка с запятой». Реализуется в лоб. И начинается медленный и печальный процесс отсечения лишних срабатываний. Анализируется порядка и 80 проектов. Происходит многократное модифицирование правила, чтобы оставить верные сообщения, убрав максимально ложные. И так индивидуально с каждым правилом. Каждый раз новые способы снизить ложные срабатывания. Это интересно. Но никаких особенных обобщенных интересных идей здесь нет. Каждый случай слишком индивидуален. Не описывать же их все. :)

Но я всё равно обещаю подумать на д статьёй или циклом статей.
Ну вы же сами уже почти предложили идею интересной статьи ;)

Опишите «историю» какого-либо интересного диагностического правила, которое претерпело множество изменений в процессе «доведения до ума». Как вы боролись с ложными срабатываниями, как максимизировали верные ;)
Я иногда вижу ваши статьи, но не очень старательно за ними слежу, поэтому может вы уже писали об этом. Но интересно, вы сам PVS-Studio анализировали? Есть ошибки?
Все ответы в одном месте. :)
Поделили размер указателя на размер структуры и получили 0. Что вообще здесь хотели сделать?


Найти количество элементов в массиве судя по всему. Кстати, распространенная ошибка. Еще бывает sizeof(Something*123) или даже sizeof(SOME_CONST). Почему-то sizeof часто понимают неправильно, а он и не возражает конечно же.
«Поделили размер указателя на размер структуры и получили 0. Что вообще здесь хотели сделать? WTF?»
Известно что. Это старая злобрая сишная идиома countof
#define countof(some_array)   ( sizeof(some_array) / sizeof(some_array[0]) )

typedef struct { char x[10]; } BigData;

int main() {
BigData bigs[100];
char smalls[100];

BigData *pbigs = bigs;
char* psmalls = smalls;

printf("%d / %d / %d / %d\n", countof(bigs), countof(smalls), countof(pbigs), countof(psmalls)); /* 100 / 100 / 0 / 4 или 8 */
return 0;
}

она хорошо работает на массивах в прямой видимости, и плохо — на указателях, к которым массивы приводятся.

Обычно такая ошибка дублируется передачей массива в подпрограмму, но тут переменная объявлена как указатель изначально, в том-то и хохма.
Бездумно скопировали. На то она и идиома, чтоб экономить на раздумьях… иногда фатально.
Надо сделать форк вашего анализатора, WTF Studio
Кнопку "Опубликовать баг в <...> с хештегом #WTF".
Кстати хорошая идея — можно выпустить на 1е апреля ап с изменённым лого :)
У нас в java-проекте есть аннотация @WTF, которую можно повесить на что угодно (класс/метод/декларация перменной). Вроде

@WTF(reason = WTFReason.UGLY, value = "Refactor this")
public static void holyCrap()
НЛО прилетело и опубликовало эту надпись здесь
Нет. Причины:
1) Статический анализ в Clang, это всего лишь один из компонентов. В результате, специализированные решения (например, PVS-Studio) будут лучше. Собственно, это можно видеть из: проверка N1, проверка N2. И нет никакой гарантии, что в угоду чего-то, эта часть вообще не исчезнет из компилятора. Я слишком пессимистичен? Отнюдь. Слышали про статический анализатор в компиляторе Intel C++? Его одно время активно продвигали. А сейчас, отдел который им занимался расформирован. Анализатор ещё вроде как есть. Как я понимаю, его не стали (пока) выпиливать. Но он не развивается. У компании Intel есть более насущные направления. А между прочим, этим анализатором нас тоже пугали — раз делает Intel, то куда уж другим.

2) У Clang плохо с Windows. Уверен, его доточат, чтобы собирать нормально Chromium под Win. Но вряд ли более. Так что чуть в сторону, и фиг соберешь проект, и фиг проверишь. По поводу «поправить самому» — см. пункт третий.

3) От Clang нельзя ожидать хорошей, а тем более оперативной поддержки. Это плата за бесплатность. :) Нет, конечно, можно заплатить, и люди доделают за деньги что-то вам. Но правда это уже совсем не бесплатный вариант. И все равно не быстро. Править что-то самому в таких сложных проектах — боже упаси. Мы же очень активно работаем с нашими пользователями, помогая им с бедами и нередко выдавая исправленную/доточенную версию PVS-Studio в течении двух-трех дней.

НЛО прилетело и опубликовало эту надпись здесь
Ну знаете, никто не скажет, что у них цель — куча ложных срабатываний. У всех цель, чтобы минимально… Но вот не получается.
«Доставляют» и другие конструкторы. Например, вот это мило:

struct ParserString : public UnionString
{
  ParserString()
  {
    UnionString::str = 0;
    UnionString::length = 0;
  }

  ParserString(const int& val)
  {
    ParserString();
  }
};


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


Хоть код и ужасен, но вы не совсем правы — данный код таки работает и делает что от него требуется, и создания нового анонимного обьекта тут не происходит. Данный код эквивалентен следующему:

struct ParserString: public UnionString
{

     ParserString()
     {
           this->UnionString::str = 0;
           this->UnionString::length = 0;
     }
...


Пруф
В качестве пруфа приведу такой код:
struct UnionString
{
	int str;
	int length;

	UnionString() : str(7), length(12) {}
};

struct ParserString : public UnionString
{
  ParserString()
  {
    UnionString::str = 13;
    UnionString::length = 666;
  }
};

int main()
{
	ParserString ps1;

	printf("%d %d\n", ps1.length, ps1.str);

	return 0;
}


На выхлопе получаем «13 666», а не «7 12»

Ошибка там не в первом, а во втором конструкторе (с аргументом), который пытается вызвать первый, а на самом деле создаёт временный объект.
Точно, ваша правда, просмотрел
Я переживаю. Мне кажется, очень многие отказываются использовать статический анализ, посмотрев предупреждения на тестовых запусках и посчитав их глупостями. Эх.
Интересно, чем руководствуются те, кто минусуют карму за комменты подобные моему комментарию выше? Неужели они никогда не делают ошибок?
НЛО прилетело и опубликовало эту надпись здесь
Вы там запятую пропустили, видимо за это.
Картинка с котиком? Не уж-то картинки с блюющим единорогом закончились?)
А я ничего странного не вижу.
Будь лично я богом программирования с запредельной памятью и внимательностью, я бы глядишь никогда и не допускал подобных «глупых» ошибок(считаю изрядную часть их простой невнимательностью).
И вот тут как раз более надёжные языки, структуры данных и более высокоуровневые библиотеки типа linq дают огромное преимущество- в них просто бы не ошиблись в инициализации переменной цикла, потому что не стали бы писать цикл, а наваяли бы Select/foreach в котором такая проблема невозможна.
И вообще бы не стали втупую писать в файл, а например сериализовали бы объект/структуру данных.
Они хороши как раз тем что они позволяют избегать тупых ошибок по невнимательности:
1. Во-первых там скрыты детали реализации и код становится чище от них- написано ЧТО делать, а не КАК делать. Соответственно и мест для ошибки становится намного меньше.
2. Во-вторых некоторые высокоуровневые языки(сейчас смотрю F#) делают анализ кода в тех местах где раньше такое не делалось. Там по умолчанию not-null объекты, паттерн-матчинг(навороченный аналог switch-case) просто не скомпилируется если обработаны не все ветви. Т.е. отсекается огромный пласт ошибок еще на этапе компиляции. Вероятность того что программа будет работать и работать правильно амного выше

В общем, я очень понимаю почему программисты тянутся к высокоуровневым языкам и инструментам, допуская при этом глупые ошибки. Именно потому что люди не идеальны, хочется чтобы твой инструмент помогал написать правильный и надёжный софт, а не подставлял очередную возможность выстрелить себе в ногу.
Да, но странность в том, что не все тянутся.
Почему странность? Не везде возможно использовать такие инструменты.
Согласен. Но это тоже странно…
Да в общем-то тоже ничего странного. Даже те кто тянутся зачастую не могут(не дают по работе)/ленятся делать всё правильно. Особенно когда язык не подталкивает к правильному пути(а зачастую наоборот).
Есть много случаев когда надо «здесь и сейчас», иногда просто лень и очень велик соблазн сделать мелкое изменение вместо рефакторинга этого куска кода(а то и всего проекта).
Все мы люди, и время от времени ошибаемся. Например у нас на проекте есть хорошее правило запускать тесты перед коммитом. Но где-то раз из 20ти я забываю это сделать(чаще всего когда делаю мелкие быстрые фиксы).
Или просто люди не знают как ьможно сделать лучше либо привыкли делать как раньше, им так может быть даже более-менее удобно
В общем, я не очень верю в людей которые никогда не совершают ошибок и пишут в соответствии со всеми правилами хорошего написания кода которые знают. Есть миллион причин чтобы «срезать углы», и многие из них даже объективны
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Информация

Сайт
pvs-studio.ru
Дата регистрации
Дата основания
2008
Численность
51–100 человек
Местоположение
Россия
Представитель
Андрей Карпов