Как стать автором
Обновить

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

Нужен для древнего for-цикла:
char *a, *b, *end;
for (; a < end; ++a, ++b) *a = *b;
м… т.е. для того, чтобы не выносить в блок for две строчки, ввели отдельный оператор?
Вообще-то, запятая — это полноценный оператор Си еще с древних времен, означает он примерно «вычислить два выражения, отбросить результат первого, а результатом считать результат второго». Цикл for тут ни при чем.
И чаще всего, как и с некоторыми другими перегружаемыми операторами в C++, лучше так не делать )
Да, мы с коллегой как-то фантазировали на тему «шаблонного оператора запятая». Потом поняли, что игра не стоит свеч, потому что мультиметодов в плюсах нет :D Но естественно, это так, без практического применения.
Вроде в CBLASe он используется, кстати.
это можно записать и без запятой
for (; a < end; ) *a++ = *b++;
нет, это полный эквивалент предыдущей конструкции
чем это принципиально отличается от хрестоматийного примера из «Язык программирования Си» Кернигана и Ричи?

void strcpy (char *s, char *t)
{
    while (*s++ = *t++)
	;
}
qw1 дело говорит, UB тут не будет, хотя такой код я бы не писал. Инкременты, затем присваивание, так в Си (как минимум).
Вообще, эквивалентом будет такой код:
*a++ = *b++;
/////////////////////
int i = 0;
a[i] = b[i];
i++;
нельзя забывать про то, что оператор инкремента может быть перегружен
В данном примере, для типа char* — не может.
Пример, которому не стоит следовать, но я видел в одной числодробилке фреймворке для математического моделирования перегруженную запятую для matlab-like инициализаци векторов.

MyVectorClass m = 1.0, 4.0, 3.0;
Хорошо, что с появлением std::initializer_list в с++1x эти костыли с перегрузкой запятой больше не нужны.
Идея статического анализа в том, что многие ошибки и опечатки можно найти на самом раннем этапе. Используйте его регулярно, и вы существенно сократите время, которое тратите на поиск и устранение дефектов.
Я вам сейчас один вещь скажу, вы только не упирайтесь. Берите пример с Resharper/CLion и вообще с продуктов JetBrains.

  • Показывайте предупреждения когда человек код печатает, а не компилирует. Запускайте компиляцию в фоне, пишите свой парсер, не важно. Важна оперативность. Не увещевайте человека регулярно прогонять ваш анализатор, делайте это за него.
  • Подсвечивайте проблемы прямо в коде, подчёркивая его волнистой линией. Смотреть ваш толстый список ошибок никому не интересно.
  • Приходите к пользователю не с проблемой, приходите с решением, а именно со списком готовых автоматический действий на выбор для исправления.

Именно из-за удобства использования ни у кого не возникает вопроса, зачем в решарпере статический анализатор. Именно работа над юзабилити (а не над детектами новых типов дефектов) может вам дать рост полезности продукта в разы.
НЛО прилетело и опубликовало эту надпись здесь
Это можно сделать опцией. Вы не будете включать её.
НЛО прилетело и опубликовало эту надпись здесь
Если эта опция будет востребована — то трудоёмкость будет оправдана.

CLion и использующие clang api IDE как-то же справляются.
НЛО прилетело и опубликовало эту надпись здесь
А в какой момент он готов может решить только написатель этого кода, явно. Ну или такой AI, уровень которого мне представить сложновато :)


И даже в случае Ai это будет только написатель кода :) Будет вообще весело: сам себя написал, сам себя проверил.
Он уже есть.
clion подсвечивает базовые вещи, так же как и сама Idea (по работе java занимаюсь в основном)
когда же в clion дело доходит до плотной работы с шаблонами он на некоторых проектах просто зависает: поток анализа уходит в разворачивания шаблонов, ui ждет его, неважно сколько ты времени будешь ждать (ждал до 2х часов). работать в clion на том проекте невозможно, так как он зависает уже на навигации (к слову сказать раньше зависал уже через 2 минуты, сейчас и 5-10 может работать, но вызов анализа кода гарантированно вешает)

компиляторы работать с препроцессорами умеют в разы лучще, просто за счет того, что это одно из узких мест в компиляции c++ кода.

поэтому и стоит разделять:
1) простейшие подсказки со стороны ide работающие online
2) глубокий анализ offline, когда мы не связаны условиями к отзывчивости системы (не думаю, что кому-то понравится когда смена одного define поставит систему на колени переиндексацией)
Вы сейчас говорите не о необходимости и удобстве фич, а о тормознутости существующих на рынке решений. Следует разделять эти понятия. И да, ReSharper C++ вроде как пошустрее CLion работает за счёт использования нативного, а не managed-парсера.
НЛО прилетело и опубликовало эту надпись здесь
в большинстве случаев (допускаю, что у вас в команде это не так, но говорю про свой опыт) статический анализатор с максимумом проверок запускается:
  1. перед комитом самим разработчиком
  2. билдсистемой на ветке, даже если патч и не ломает билд/тесты, а всего лишь увеличивает количество warnings, то патч ещё нужно дорабатывать


почему я считаю, что мощный статический анализатор online не нужен:
  1. считать все шаблоны и подстановки define в online это тяжело (тут думаю даже примеры приводить не нужно, достаточно по хабру поискать примеры кода которые не могут даже компиляторы переварить). сюда же можно записать, что изменение одного define для сборки может затронуть половину кода, в итоге мы кушаем все ядра и стараемся дать ответ максимально быстро или мы пересчитываем все на одном ядре к моменту, когда пользователь уже давно ушел с этого куска.
  2. считать все пути выполнения кода и возможные значения входных переменных online тоже тяжело (нас не интересует разыменование указателя как таковое, везде ставить проверки устанешь, нас это может волновать, если анализатор скажет, что сюда в некоторых условиях может придти нулевой указатель и тогда все упадет)
  3. в большинстве случаев online нужен с ограниченным функционалом, так как всё равно все сконцентрированы на том, чтобы реализовать работающую логику, пускай и без проверки граничных условий. дополнительные варнинги будут только сбивать с мысли, а уже когда видишь, что алгоритм вроде работает и начинаешь причесывать код к комиту, то тут и пора запускать анализатор и я как пользователь готов ждать и 5 минут (схожу за кофе) и 1 час (начну смотреть другой таск), пускай он в фоне работает и генерит вывод максимально корректно, а я по приходу посмотрю список «ошибок»


в моем понимании стоит разделять «базовые проверки» (когда мы в пределах блока кода или метода пытаемся что-то делать, та же копипаста в методах и одинаковые условия в if) и «мощный статический анализатор» (который анализирует весь control flow graph и указывает, что нам откуда-то что-то веселое приходит, а мы это совсем не ждем). первое уже везде в разном виде присутствует, а вот второе всегда было и останется offline, просто из-за того, что по мере того как фиксятся тормоза в одном месте и появляются ресурсные мощности, мы хотим добавить «ещё и вот эту проверочку».
Для онлайн-анализа самое важное — это обнаружение опечаток.
Компилятор их найдёт, но это десятки секунд потерянного времени.

Но любой анализ, будь он глубоким или «базовым», должен работать абсолютно надёжно, иначе он будет только раздражать. В случае с с/с++ без процессинга всех include и define невозможно сказать, опечатка это или макрос. Поэтому «базовая проверка» всё равно будет очень тяжёлой и разница между ней и полной может быть совсем небольшая, чтобы полную проверку выносить в отдельный режим.
Спасибо за подробный комментарий, Вы абсолютно правы. По всем пунктам.

Посмотрите, пожалуйста, на режим инкрементального анализа в PVS-Studio (в документации). На наш взгляд это как раз шаг в заданном направлении. Как думаете?
Инкрементальный анализ — это хорошо, но он является необходимым, но не достаточным шагом. Просто суть в том, что главный враг даже не проблемы в коде, а человеческая лень.
Анализаторы кода нужны практически везде (как и грамотное тестирование приложений).

Так как вы привели пример с картинками, я тоже приведу похожий.
В системе Android картинки (кроме формата png, bmp, jpg и т.д.) могут быть описаны файлом в формате xml.
Обычно иконку приложения описывают как именно картинку, и это не вызывало проблем. Но появился разработчик, который вместо png файла вставил xml файл. Очевидно, что все должно было работать, ведь система поддерживает данный формат. Оно и работало — на большинстве телефонов, кроме модели от Sony. У данной модели была своя реализация UI для телефона, которая не предусмотрела xml как входной формат. Телефон пытался отобразить картинку, у него не получалось, он перезагружался и цикл повторялся.

Статический анализатор вполне мог бы указать, что switch-case блоки для всех типов в enum, кроме xml.
Статический анализатор вполне мог бы указать, что switch-case блоки для всех типов в enum, кроме xml.


Кланг так умет. GCC не помню, вроде бы тоже.
А мне больше всего нравятся ошибки которые проявляются в зависимости от того какое количество раз выполняется тот или иной код. Например — четное количество раз результат выдается верный. Нечетное количество раз — результат неверный.
Словом, чем больше разноплановых систем контроля корректности работы продукта тем лучше. Сложность современных продуктов давно уже вышла за рамки, когда контролировать их качество в состоянии даже группа людей.
… Эта библиотека отлажена и протестирована. Её использует огромное количество разработчиков по всему миру. В ней просто не может быть ошибок, лежащих на поверхности...

Это вы слишком уж категорично заявляете. Свсем уж критических ошибок, да, не будет, но мелкие — вполне себе могут быть. Если взять ОС Windows 7, которую использует несчетное количество пользователей, то там прямо на поверхности лежит баг со сплиттером и курсором в интерфейсе, который бесит неимоверно, и до сих пор не поправлен.
Неприятность тут вот в чём — при перемещении сплиттеров-разделителей в эксплорере Windows 7 они не всегда захватываются мышью.
Воспроизводится это так: запустите эксплорер (Win+E), подведите курсор к вертикальному разделителю между основным окном и окном предварительного просмотра, затем аккуратно сдвиньте курсор на пару писелов влево или вправо. Обратите внимание, что вид курсора — по-прежнему двойная стрелка, показывающая, что мы можем захватить разделитель. Теперь аккуратно нажмите кнопку мыши, стараясь не сдвинуть указатель — в результате курсор сменится на стрелочку и разделитель захвачен не будет. В обычной работе это проявляется так, что при перемещении сплиттеров туда-сюда они то захватываются то нет. Пользователь про себя матерится и делает перемещение снова. У меня трекболл вместо мыши и я вижу эту проблему в полный рост, потому что на трекболле при нажатии кнопки я шарик вообще не трогаю.

Вот здесь на тостере я более подробно написал:
Проблема со сплиттерами-разделителями в Windows Explorer (Win 7)

Вынесу также коммент RaMMicHaeL из своих личных сообщений:
"Я взглянул на проблему.
Во первых, код, отвечающий за баг, принадлежит не проводнику, а файлу duser.dll (DirectUser). Для того чтобы решить, какой курсор показывать, вызывается функция DirectUI::HWNDElement::ElementFromPoint, которая возвращает неправильный элемент.
Эта функция вызывает функцию DuVisual::FindFromPoint, которая также возвращает не то.
Пока я это все писал, я нашел баг! :)
Обрабатывая WM_SETCURSOR, для получения координат мыши в Windows 7 использовалась функция GetMessagePos, которая возвращала предыдущие координаты. Windows 8 использует GetCursorPos.
Найти местоположение кода легко — нужно поставить бряк на SetCursor, GetMessagePos будет немного выше.
"

Зная о проблеме, я перемещаю сплиттеры аккуратно (всё руки никак не дойдут это дело поправить). Но страшно представить, какое огромное количество пользователей семёрки натыкаются на это дело (лежащее, согласитесь, совсем уж «на поверхности»), но списывают это дело на тремор в суставах, а на самом деле там просто откровенный баг. Причём выпустить патч — проблема небольшая. В майкрософт писал, но это дело осталось без ответа (да, собственно в восьмёрке пофиксено).
(да, собственно в восьмёрке пофиксено)
Не совсем. В проводнике, на панели предпросмотра оно осталось, если выделить текстовый файл и вести в правую сторону. Только в таком случае можно повторить, во всех остальных случаях не повторяется.
Спасибо за коммент. Я сам это почти не проверял, так как до сих пор на семёрке сижу, но сходу устойчиво воспроизвести не удалось. Надо будет на досуге в Win10 посмотреть. В принципе такая же проблема есть и с выделением файлов и перетаскиванием их из окошка в окошко — иногда вместо ожидаемого перетаскивания они начинают выделяться. Впрочем тут это багом назвать сложно, скорее проблемка с юзабилити. Я просто время от времени на тестировке сижу и когда наблюдаемый результат отличается от ожидаемого — автоматически начинаю разбираться.
Кстати, проверил в Win 10. У меня пока Build 9841. Тоже не без греха — там сплиттер иногда тягается за курсором, вид которого не соответствует действию:

Ну, окей, тут можно списать на Technical Preview, либо на VMWare. Но если именно так уйдёт в релиз — то будет грустно. Оно вроде мелочь, но такие залипушки в ПО такого уровня иметь место не должны.
НЛО прилетело и опубликовало эту надпись здесь
Ознакомительный режим PVS-Studio.

Ограничения время от времени меняются в порядке эксперимента и достижения лучшей конверсии. Поэтому здесь текущий вариант не пишу.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий