从夹板边界检查的奇怪行为

时间:2011-11-22 23:09:11

标签: c arrays bounds splint

那里有任何夹板专家吗?我正在尝试使用splint静态分析我在C中的一个大型项目。我看到过多的边界检查错误显然不是绑定错误。我写了一个小测试程序试图找出问题,并在我对代码运行splint时注意到一些非常奇怪的警告。我有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. 有没有办法让splint不增加超出其边界的数组的大小?现在夹板报告了超过750个警告,我没有时间逐个验证每个警告。

1 个答案:

答案 0 :(得分:1)

预先:我不知道'夹板',但我非常了解使用PC Lint的技术,并与其制造商讨论了几个问题。

那说:

  • 在您的第一个示例中,arr[3]仅标记为+bounds,因为一个过去的元素是一个特殊情况:允许创建并使用指向过去元素的指针最后一个,但不允许取消引用这样的指针。因此,在语法检查器(QA-C)中,经常发生这样的警告对N + 1不太严重。你试过arr[4]了吗?我的猜测是,+likely_bounds就足够了。
  • 第二个例子可能是由一个有点混乱的“夹板”引起的。我在早期版本的PC Lint和QA-C中看到过类似的错误,因为“价值追踪”并非易事。但是,我不知道为什么分裂在抱怨。
  • 你的第三个例子,'夹板'正在抱怨初始化arr[3],但出于价值追踪的目的,它假设arr[3]有效,并且不要抱怨循环。我猜你可以初始化arr[100]并让循环运行到100而不抱怨!