那里有夹板专家吗?我试图使用夹板静态分析我在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]生成警告。看来写到数组的末尾会扩大夹板认为数组的大小。那怎么可能?

简而言之,我的问题是:
  • 可能性限制标志有什么作用?
  • 有什么方法可以使夹板给我有关超出范围的合法错误?
  • 是否有任何方法可以使夹板不增加超出其界限访问的数组的大小?目前,夹板报告了750多个警告,我没有时间来逐个验证每个警告。
  • 最佳答案

    预先说明:我不知道'splint',但是通过密集使用PC Lint并与制造商讨论几个问题,我对这些技术非常了解。

    说:

  • 在您的第一个示例中,arr[3]仅使用+bounds进行了适当标记,因为后一种元素是一种特殊情况:允许创建和使用指向后一种元素的指针,但不允许取消引用这样的指针。因此,在语法检查器(也包括QA-C)中,这种警告对于N + 1不太严重。您尝试过arr[4]吗?我的猜测是,+likely_bounds就足够了。
  • 第二个示例可能是由于有点困惑的“splint”引起的。我已经在早期版本的PC Lint和QA-C中看到了类似的错误,因为“值跟踪”远非易事。但是,我不能说出为什么 split 正在提示。
  • 第三个示例“splint”正确地提示初始化arr[3],但是出于值跟踪的目的,它假定arr[3]是有效的,并且避免提示循环。我猜您可以初始化arr[100]并让循环运行到100,而不会提示!
  • 关于c - 夹板界限检查的奇怪行为,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/8235204/

    10-14 06:37