Нечетное поведение при проверке границ шины - PullRequest
6 голосов
/ 23 ноября 2011

Есть ли эксперты по шинам?Я пытаюсь использовать splint для статического анализа большого проекта, который у меня есть в C. Я вижу избыточное количество ошибок проверки границ, которые явно не являются ошибками границ.Я написал небольшую тестовую программу, чтобы попытаться изолировать проблему, и заметил несколько действительно странных предупреждений, когда запускал шину по коду.У меня есть 3 разных примера.Вот первое:

int arr[3];

int main(void)
{
    int i;
    int var;

    arr[3] = 0; // (1) warning with +bounds, no warning with +likely-bounds

    return 0;
}

Назначение arr[3] генерирует предупреждение при использовании +bounds, как и следовало ожидать, но ничего не делает, когда я использую +likely-bounds.Что делает +likely-bounds?Кажется, не работает.Второй пример:

int arr[3];

int main(void)
{
    int i;
    int var;

    for (i = 0; i < 3; i++)
        var = arr[i]; // (2) warning, even though I'm within the bounds.

    return 0;
}

В этом примере splint жалуется, что я читаю за пределами массива («Чтение памяти ссылается на память за пределами выделенного хранилища.») Для var = arr[i], хотяЯ, очевидно, нет.Это должно быть предупреждением, потому что значения в массиве не инициализируются, но это не предупреждение, которое я получаю.Инициализация последнего значения в массиве очистит ошибку (но инициализация первого или второго не даст).Я делаю что-то неправильно?В третьем примере:

int arr[3];

int main(void)
{
    int i;
    int var;

    arr[3] = 0; // warning

    for (i = 0; i < 4; i++)
        var = arr[i]; // (3) no warning because arr[3] = 0 statement.

    return 0;
}

Предупреждение генерируется для arr[3] = 0, но не для var = arr[i], хотя очевидно, что цикл выходит за границы массива.Похоже, что запись в конец массива расширяет представление о том, насколько массивен массив.Как это возможно?

Короче говоря, мои вопросы:

  1. Что делает флаг вероятных границ?
  2. Есть ли способ, которым я могу заставить шину дать мне законные ошибки, которые относятся к выходу за пределы?
  3. Есть ли способ заставить шину не увеличивать размер массивов, к которым осуществляется доступ за их пределами?В данный момент шина сообщает о более чем 750 предупреждениях, и у меня нет времени проверять каждое предупреждение одно за другим.

1 Ответ

1 голос
/ 26 ноября 2011

Предварительно: я не знаю «шины», но я хорошо знаю методы, благодаря интенсивному использованию PC Lint и обсуждению нескольких вопросов с его создателями.

Это говорит:

  • В вашем первом примере arr[3] помечается только с вероятностью +bounds, потому что элемент, следующий за последним, является особым случаем: можно создавать и использовать указатель на элемент, который следует за последним, но не допускается разыменование такого указателя. Поэтому в средствах проверки синтаксиса (также QA-C) довольно часто случается, что такие предупреждения менее серьезны для N + 1. Вы пробовали arr[4]? Я думаю, +likely_bounds будет достаточно для этого.
  • Второй пример, вероятно, вызван несколько запутанной «шиной». Я видел подобные ошибки в ранних версиях PC Lint и QA-C, поскольку «отслеживание значений» далеко не просто. Однако я не могу сказать, почему Сплит жалуется.
  • Ваш третий пример, 'splint' правильно жалуется на инициализацию arr[3], но для целей отслеживания значений он тогда предположил, что arr[3] является действительным, и воздерживается от жалоб на цикл. Я предполагаю, что вы могли бы инициализировать arr[100] и позволить циклу работать до 100 без жалоб!
...