Мы пишем код внутри ядра Linux, поэтому, как я ни старался, я не смог заставить PC-Lint / Flexelint работать с кодом ядра Linux. Просто слишком много встроенных символов и т. Д. Но это побочный вопрос.
У нас есть любое количество компиляторов, начиная с gcc, но также и другие. Их параметры предупреждений с течением времени становились все более мощными, и это тоже довольно мощный инструмент статического анализа.
Вот что я хочу поймать. Да, я знаю, что это нарушает некоторые вещи, которые легко уловить в обзоре кода, такие как «без магических чисел» и «остерегайтесь сдвига битов», но это только в том случае, если вы случайно посмотрите на этот раздел кода. Во всяком случае, вот оно:
unsigned long long foo;
unsigned long bar;
[... lots of other code ...]
foo = ~(foo + (1<<bar));
Дальнейшее ОБНОВЛЕНИЕ описания проблемы - даже с баром, ограниченным 16, все еще проблема. Пояснение: проблема заключается в неявном типе константы типа int, который незапланированно заставляет сложное выражение нарушать правило, согласно которому все вычисления должны выполняться в одинаковом размере и подписи.
Проблема: '1' не длинный, но, как константа с небольшим значением, по умолчанию используется int. Следовательно, даже если фактическое значение бара никогда не превышает, скажем, 16, выражение (1<<bar)
все равно будет переполнено и разрушит весь расчет.
Возможно правильное решение: вместо этого напишите 1ULL.
Есть ли хорошо известный флаг предупреждения компилятора и компилятора, который укажет на эту (исправленную) проблему?