LINUX.ORG.RU

Werror - контроль качества или занудство?

 ,


0

4

Все, кто занимается низкоуровневым жонглированием байтами в реалых промышленных условиях (с кучей поставщиков со всего мира, а не в уютненьком молодёжном стартапе где-нибудь в Саннивейл), понимают, что C’шка с нами надолго, лет на 20, если не больше. И поэтому возникает желание максимально использовать существующие технологии для обеспечения качества кода.

Например, Werror (и то, что к нему полагается в виде -Wall, -Wextra и проч.). Но возникают такие ситуации, как например с «целочисленным повышением» и последующим сравнением с разным знаком. Например:

const unsigned x = 12;
unsigned char y;
unsigned char z;
... // что-то кладём в y и z
if (x < (y*z))
{
   // тра-ля-ля
}

И y*z превращаются («брюки превращаются, превращаются брюки…») в элегантный int, и вылезает предупреждение о различной знаковости, как бы совершенно на ровном месте. Т.е. теперь, чтобы ублажить компилятор, надо дополнительно, например, явно кастануть x к int’у. Т.е., код уже на пределе читаемости (выше пример - это сильное упрощение возможной реальной ситуации), и тут мы ещё добавляем вовсе не интуитивный (int).

И возникает вопрос: а стоит ли овчинка (-Werror и ко.) выделки? Я сейчас, очевидно, не имею в виду код наивысшей критичности, а такой, который при случае можно просто неспеша поправить, в конце рабочего дня, с нулевыми последствиями для пользователей, окружающей среды и т.п.

P.S. кстати, поскольку в расте тоже есть беззнаковые типы, там тоже нечто подобное должно быть, или как?

UPD: в примере, в нагрузку к умножению надо ещё добавить сложение с ещё одним unsigned char.

★★★★★

Последнее исправление: seiken (всего исправлений: 1)

С одной стороны не встречался с ситуацией, чтобы эти предупреждения находили баг в моём коде.

С другой стороны всегда включаю все предупреждения и легко настраиваемые линтеры.

Считаю, что код это улучшает. Даже если баги и не находит. Ну и может это я один такой умный, а всем остальным помогает…

vbr ★★★★★
()
Ответ на: комментарий от vbr

С одной стороны не встречался с ситуацией, чтобы эти предупреждения находили баг в моём коде.

Довольно интересно и весьма полезно открыть man gcc и поразмышлять почему варнинги это варнинги, т.е. чем плох такой код на который они срабатывают.

soomrack ★★★★★
()
Ответ на: комментарий от vbr

С одной стороны не встречался с ситуацией, чтобы эти предупреждения находили баг в моём коде.

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

Например, до момента X предполагалось, что входной параметр может принять только значения [v1, v2], а в момент X кто-то подал на вход v3 за пределами данного диапазона. И не он виноват, что это привело к целочисленному переполнению, потому что тип аргумента позволяет хранить в нём v3, и нигде не задокументировано, что нельзя передавать v3.

В Аде можно создавать кастомные целочисленные типы легко и просто:

subtype Voltage is NonNegative range 0 .. 220;

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

seiken ★★★★★
() автор топика
Ответ на: комментарий от seiken

А в сишке таких проверок нет, и может произойти порча памяти, со всеми вытекающими последствиями.

разумеется, всё не так фатально. В сишке просто все операции, могущие привести к переполнению, надо явно проверять заранее в рантайме на переполнение. Но, блин, кто так делает? Считанные единицы. Для остальных - если скомпилировалось, то всё ОК.

seiken ★★★★★
() автор топика