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

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

А зачётная ошибка, мне понравилась :)

Кстати, в языках типа Swift нельзя просто так взять и написать код в фигурных скобках. Надо написать do {… }. То-есть явно указать что это блок кода, не связанный с if или for. Может, оно и не зря...?

Что в Swift лично мне всё таки не нравится: До него я иногда использовав скобки для разделения логических блоков внутри метода или для изоляции областей видимости переменных. В Swift же "{ }" — корректное замыкание.
Я если без фигурных скобок, пишу
if () a=b;
else a = c;
но в этом и только этом случае. Если одна из веток в скобках, то и вторая обязательно тоже.
Думаю для неMISRA случаев стоит отлавливать ситуацию когда внезапно после безскобочного if появляется «бесхозный» блок в фигурных скобках. Может быть даже вообще для всех таких вот «бесхозных» блоков выводить предупреждение?
Когда дойдём до реализации, мы ещё подумаем над вариантами на что ругаться.
На самом деле весьма распространенный вид бага только классический вид:
if (condition);
{
// block
}
Это анализатор уже ловит диагностикой V529. Реальные примеры ошибок в открытых проектах.
В вашем случае чаще всего нагляднее сделать:
a = condition? b: c;
(конечно, я бы это делал только если condition небольшой и без вложенных тернарников — в них сложно разобраться).
Но в общем понятно, о чем вы.
Про тернарный оператор я, конечно, знаю. Но мы ведь не это обсуждаем.
Если посмотреть на тело того, что в «фигурных скобках», и на сам условный оператор — то никакой зависимости одного от другого нет.

Т.е. фигурные скобки здесь поставлены по каким-то другим причинам, и не относятся к условному оператору.

Некоторые ставят «лишние» скобки для выделения смысловых блоков с точки зрения улучшения читаемости.

Так что однозначно говорить, что вы нашли именно реальный баг, а не ложное срабатывание эвристики — нельзя.

Для правильного определения этого надо смотреть историю коммитов — появился ли блок сразу целиком, или был какой-то момент, когда он реально относился к этому условному оператору?

Есть ли в PVS-студии какие-нибудь инструменты для анализа с учётом изменений кода со временем? Чтобы рассматривать не весь текущий код, а только внесённые изменения?

При таком подходе можно использовать гораздо больше эвристик — при сотне строчек изменений миллион предупреждений точно не возникнет.

Всегда странно, что люди хотят оправдать какой-то код или найти в нём какой-то высший смысл :). Даже если здесь нет ошибки, это код плох, так как вводит в заблуждение и анализатор и людей, которые будут сопровождать этот код. Другими словами, этот код с сильным с запахом. И он в любом случае требует к себе внимания и правок / рефакторинга.

Это что же за код такой, который нельзя понять без истории коммитов? Спасибо, не надо.

История коммитов используется не для того, чтобы понять код, а чтобы понять, как именно этот код был получен — и где именно ошибка.
Например, частый гость в статьях PVS — копирование куска кода, при котором забывают исправить какое-то из условий. В таком случае история может показать, какой именно кусок — начальный, а какие — скопированные, и какие именно условия некорректны.
Есть ли в PVS-студии какие-нибудь инструменты для анализа с учётом изменений кода со временем? Чтобы рассматривать не весь текущий код, а только внесённые изменения?

Они утверждают, что вариант типа есть отчёт по предыдущей версии кода, при анализе новой версии показываются только новодобавленные предупреждения — реализует это. Но при первом анализе надо пересмотреть всё. По-моему, это скорее правильно.

Данная опечатка характерна для стиля кода, в котором сочетаются 2 правила.


  1. Допускается действие по условию без скобок.
  2. Открывающая блок скобка занимает отдельную строку.

Если придерживаться соглашений, где каждое действие по условию обязательно помещается в блок, и(или) открывающая блок скобка размещается на строке, управляющей этим блоком, то такие ошибки просто не могут появиться.


if (condition) {
    doThis();
} else {
    doThat();
}

Как говорится, нормально делай — нормально будет.

Однако рекомендовать всем подряд использовать фигурные скобки – это плохая идея.

Это хорошая идея, IMHO, и хорошо, что большинство новых языков так или иначе это требуют.
Пара добавочных {} занимает всего несколько байт (считая пробелы), зато устраняет ситуации типа "забыли поставить {} при добавлении оператора".


А для просто блока в {} — жаль, что C не позволяет do { действия }; — да-да, без while после. (Хак с while(0) известен, но сам по себе требует парсинга глазами.)


В исходном коде меня смущает форматирование. Какой-нибудь uncrustify несмотря на все его тараканы тут, по умолчанию, 1) перенесёт условие первого then на новую строку и сдвинет его, 2) вставит пустую строку перед последующим блоком — и тогда будет очень легко видно, что тут раздельные действия.


Вообще (опять же IMHO), что должно быть в правилах типа MISRA это йорсирование использования подобных форматтеров. (У меня нет доступа к полному стандарту, чтобы узнать, есть ли там такое — но если есть, отлично.)

Здесь надо разделить понятие стиля программирования и рекомендаций статического анализатора для поиска ошибок. Мы, например, сами всегда используем фигурные скобки. Однако, если анализатор начнёт предупреждать про скобки в проекте, где придерживаются другого стиля, то это такое себе… Для этого есть анализаторы стиля кодирования. Ну или можно включить те-же MISRA диагностики и насладиться месяцами рефакторинга :).
Зарегистрируйтесь на Хабре , чтобы оставить комментарий