Pull to refresh

Comments 49

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

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

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

Вопрос в том, почему вы — будучи автором программы для проверки ошибок, т.е. видимо осознавая нужность проверки ошибок — сами свои тексты на ошибки не считаете нужным проверять. Ошибки-то указанные не грамматические, не какие-то сложные, а именно те, на которые любая проверялка как на красную тряпку реагирует.
Еще раз — это абсолютно не наезд на вас. Это реально интересный вопрос из серии «почему сапожник без сапог».
Вероятно, они пытались напускать статический анализатор на статьи, но ничего не получилось.
UFO just landed and posted this here
Это уже б-м понятно, что код — отстой, а 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()
UFO just landed and posted this here
Нет. Причины:
1) Статический анализ в Clang, это всего лишь один из компонентов. В результате, специализированные решения (например, PVS-Studio) будут лучше. Собственно, это можно видеть из: проверка N1, проверка N2. И нет никакой гарантии, что в угоду чего-то, эта часть вообще не исчезнет из компилятора. Я слишком пессимистичен? Отнюдь. Слышали про статический анализатор в компиляторе Intel C++? Его одно время активно продвигали. А сейчас, отдел который им занимался расформирован. Анализатор ещё вроде как есть. Как я понимаю, его не стали (пока) выпиливать. Но он не развивается. У компании Intel есть более насущные направления. А между прочим, этим анализатором нас тоже пугали — раз делает Intel, то куда уж другим.

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

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

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

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»

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

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