Комментарии 18
А зачётная ошибка, мне понравилась :)
Кстати, в языках типа Swift нельзя просто так взять и написать код в фигурных скобках. Надо написать do {… }. То-есть явно указать что это блок кода, не связанный с if или for. Может, оно и не зря...?
if () a=b;
else a = c;
но в этом и только этом случае. Если одна из веток в скобках, то и вторая обязательно тоже.
Думаю для неMISRA случаев стоит отлавливать ситуацию когда внезапно после безскобочного if появляется «бесхозный» блок в фигурных скобках. Может быть даже вообще для всех таких вот «бесхозных» блоков выводить предупреждение?
if (condition);
{
// block
}
a = condition? b: c;
(конечно, я бы это делал только если condition небольшой и без вложенных тернарников — в них сложно разобраться).
Но в общем понятно, о чем вы.
Т.е. фигурные скобки здесь поставлены по каким-то другим причинам, и не относятся к условному оператору.
Некоторые ставят «лишние» скобки для выделения смысловых блоков с точки зрения улучшения читаемости.
Так что однозначно говорить, что вы нашли именно реальный баг, а не ложное срабатывание эвристики — нельзя.
Для правильного определения этого надо смотреть историю коммитов — появился ли блок сразу целиком, или был какой-то момент, когда он реально относился к этому условному оператору?
Есть ли в PVS-студии какие-нибудь инструменты для анализа с учётом изменений кода со временем? Чтобы рассматривать не весь текущий код, а только внесённые изменения?
При таком подходе можно использовать гораздо больше эвристик — при сотне строчек изменений миллион предупреждений точно не возникнет.
Это что же за код такой, который нельзя понять без истории коммитов? Спасибо, не надо.
Например, частый гость в статьях PVS — копирование куска кода, при котором забывают исправить какое-то из условий. В таком случае история может показать, какой именно кусок — начальный, а какие — скопированные, и какие именно условия некорректны.
Есть ли в PVS-студии какие-нибудь инструменты для анализа с учётом изменений кода со временем? Чтобы рассматривать не весь текущий код, а только внесённые изменения?
Они утверждают, что вариант типа есть отчёт по предыдущей версии кода, при анализе новой версии показываются только новодобавленные предупреждения — реализует это. Но при первом анализе надо пересмотреть всё. По-моему, это скорее правильно.
Данная опечатка характерна для стиля кода, в котором сочетаются 2 правила.
- Допускается действие по условию без скобок.
- Открывающая блок скобка занимает отдельную строку.
Если придерживаться соглашений, где каждое действие по условию обязательно помещается в блок, и(или) открывающая блок скобка размещается на строке, управляющей этим блоком, то такие ошибки просто не могут появиться.
if (condition) {
doThis();
} else {
doThat();
}
Как говорится, нормально делай — нормально будет.
Однако рекомендовать всем подряд использовать фигурные скобки – это плохая идея.
Это хорошая идея, IMHO, и хорошо, что большинство новых языков так или иначе это требуют.
Пара добавочных {} занимает всего несколько байт (считая пробелы), зато устраняет ситуации типа "забыли поставить {} при добавлении оператора".
А для просто блока в {} — жаль, что C не позволяет do { действия }; — да-да, без while после. (Хак с while(0) известен, но сам по себе требует парсинга глазами.)
В исходном коде меня смущает форматирование. Какой-нибудь uncrustify несмотря на все его тараканы тут, по умолчанию, 1) перенесёт условие первого then на новую строку и сдвинет его, 2) вставит пустую строку перед последующим блоком — и тогда будет очень легко видно, что тут раздельные действия.
Вообще (опять же IMHO), что должно быть в правилах типа MISRA это йорсирование использования подобных форматтеров. (У меня нет доступа к полному стандарту, чтобы узнать, есть ли там такое — но если есть, отлично.)
Пример, как в PVS-Studio появляются новые диагностики