Polyspace® Code Prover™ анализирует код C/C++ для ошибок времени выполнения и сообщает о результатах анализа, как проверяет операции. Проверки окрашены в зеленый, красный цвет, или оранжевые на основе того, передают ли они, перестали работать или остаются неокончательными. В дополнение к проверкам анализ также сообщает об областях значений относительно переменных в подсказках в исходном коде. Эти подсказки области значений могут поддержать расследование проверок на этапе выполнения, о которых сообщают, и также упростить более глубокое понимание кода, когда используется с другими инструментами навигации в пользовательском интерфейсе Polyspace или Polyspace доступ к веб-интерфейсу.
Например, эта подсказка на переменной beta
указывает, что переменная является локальной переменной, имеет тип данных float
(на цели, где float
имеет 32 бита), и имеет значение в области значений [0.1.. 0.5]. Область значений комбинирует значения beta
от всех возможных путей к выполнению, которые проходят через ту операцию кода.
Code Prover анализирует каждую операцию в исходном коде для всех возможных путей к выполнению посредством операции (удовлетворяющий предположениям верификации). Когда анализ сообщает об области значений относительно экземпляра переменной или операции, значений объединений диапазона от всех путей к выполнению, которые приводят к переменной или операции.
Рассмотрите следующий пример. Когда Code Prover анализирует функциональный func
, анализ сообщает о переменных диапазонах почти относительно всех переменных в функции. Комментарии к коду на каждой линии показывают переменные диапазоны, о которых сообщают в анализе Code Prover. Обратите внимание на то, что показанные области значений являются теми, которые происходят после операций на линии.
int func(unsigned int count) { // count is in [0 .. UINT_MAX] int var; if(count <= 5) var = count; //var is in [0..5] else var = 100; return var; //var is 100 or in [0..5] }
Например, вы видите переменные диапазоны в подсказках:
В начале функции.
Предположим тот func
не называется в другом месте в коде. На основе типа данных unsigned int
, Code Prover принимает тот count
может иметь значения в области значений [0.. 232 - 1] или [0.. UINT_MAX
].
В каждой ветви условного оператора.
Путь к выполнению может ввести if
ветвь if-else
оператор, только если count
меньше чем или равно 5. Поэтому в if
блок, count
может иметь значения только в области значений [0.. 5]. Переменная var
, который получает его значение от ограниченного count
, также имеет то же ограничение.
В конце, когда функция возвращается.
В return
оператор, var
может иметь любого значение [0.. 5] от if
перейдите или значение 100 от else
ветвь. Подсказка на var
в return
оператор объединяет эти две области значений и показывает область значений, 100 или [0.. 5].
Используя подсказки на переменных диапазонах, можно отследить поток данных в коде и изучить, как переменная получает значение, которое могло привести к ошибке времени выполнения.
Иногда, область значений, о которой сообщают относительно переменной, может быть более узкой, чем, что вы ожидаете. Более узкая, чем ожидалось область значений может означать, что две на вид несвязанных переменные могут быть связаны от предыдущей операции.
Рассмотрите этот пример. Комментарии к коду на каждой линии показывают переменные диапазоны, о которых сообщают в анализе Code Prover в конце операций на линии.
void func(int arg) { int first, second, diff; first = arg; assert( first >= 0 && first <= 256*400); // first is in [0 .. 102400] second = (first << 4); // second is in [0 .. 1638400] diff = (first * 16) - (second + 256); // diff is only -256 }
На первый взгляд, подсказка на diff
в последней линии может быть удивительным. Переменная first
находится в области значений [0.. 102400] и переменная second
находится в области значений [0.. 1638400], но различие diff
имеет только одно значение, -256
.
Причина одного значения diff
это предыдущая операция:
second = (first << 4);
first
и second
таким способом, который first * 16
всегда равно second
, независимо от значений first
и second
. Поэтому они отменяют друг друга на всех путях к выполнению, ведя к одному значению diff
.Если вы видите более узкие, чем ожидалось области значений в своем коде, ищете предыдущие операции, которые могут связать две из переменных, вовлеченных в текущую операцию. Можно также ввести прагму Inspection_Point
перед операцией и затем анализируют код, чтобы идентифицировать отношение между двумя из переменных в операции. Смотрите Находят Отношения Между Переменными в Коде.