Есть ли какой-нибудь инструмент для С++, который будет проверять общее неуказанное поведение?

Часто делаются предположения о конкретной платформе, на которой кодируется, например, что целые числа со знаком используют два хранилища дополнений или что (0xFFFFFFFF == -1) или такие вещи.

Существует ли какой-либо инструмент, который может проверять кодовую базу для наиболее распространенных нарушений таких вещей (для тех из нас, кто хочет иметь переносимый код, но не имеет странных машин с не-двумя дополнениями)?

(Мои примеры выше относятся к целым числам со знаком, но меня также интересуют другие ошибки (такие как выравнивание или порядок байтов)

Ответ 1

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

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

Ответ 2

Я знаю, что CLang очень активно развивает статический анализатор (как библиотеку).

Цель состоит в том, чтобы ловить ошибки во время анализа, однако точная степень ошибок, пойманных, еще не понятна мне. Библиотека называется "Checker", и T. Kremenek несет ответственность за нее, вы можете узнать об этом в списке рассылки clang-dev.

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

Ответ 3

Может быть, инструмент статического анализа кода? Я использовал его несколько лет назад, и он сообщил об ошибках, подобных этому. Это было не идеально и все еще ограничено, но, может быть, теперь инструменты лучше?

обновление: Возможно, один из них: Какие инструменты с открытым исходным кодом С++ для статического анализа доступны?

Update2: Я попробовал FlexeLint на вашем примере (вы можете попробовать его в Интернете, используя пример Do-It-Yourself на http://www.gimpel-online.com/OnlineTesting.html), и он жалуется на это но, возможно, не так, как вы ищете:

5    int i = -1;
6    if (i == 0xffffffff)
diy64.cpp  6  Warning 650:  Constant '4294967295' out of range for operator '=='
diy64.cpp  6  Info 737:  Loss of sign in promotion from int to unsigned int
diy64.cpp  6  Info 774:  Boolean within 'if' always evaluates to False [Reference: file diy64.cpp: lines 5, 6]

Ответ 4

Очень интересный вопрос. Я думаю, что было бы довольно сложно написать инструмент, чтобы отметить это с пользой, потому что так много зависит от намерений/предположений программиста.

Например, было бы легко распознать конструкцию типа:

x &= -2; // round down to an even number

как зависящее от двухкомпонентного представления, но что, если маска является переменной вместо константы "-2"?

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

[извините, не совсем ответ, но слишком долго для комментария]