3

我们在 Linux 内核中编写代码,所以尽我所能,我无法让 PC-Lint/Flexelint 在 Linux 内核代码上工作。内置符号等太多了。但这是一个附带问题。

我们有任意数量的编译器,从 gcc 开始,但也有其他的。随着时间的推移,它们的警告选项越来越强大,它们也是非常强大的静态分析工具。

这是我想要捕捉的。是的,我知道它违反了一些在代码审查中很容易发现的东西,例如“没有幻数”和“当心位移”,但前提是你碰巧看到了那段代码。无论如何,这里是:

unsigned long long foo;
unsigned long bar;

[... lots of other code ...]

foo = ~(foo + (1<<bar));

进一步更新的问题描述——即使 bar 限制为 16,仍然是一个问题。澄清一下,问题是隐含的 int 类型的常量,它在计划外使复杂的表达式违反了所有计算都以相同的大小和符号进行的规则。

问题:'1' 不是 long long,但作为一个小值常量,默认为 int。因此,即使 bar 的实际值从未超过,例如 16,(1<<bar)表达式仍然会溢出并破坏整个计算。

可能正确的解决方案:改为写 1ULL。

是否有一个众所周知的编译器和编译器警告标志会指出这个(修订的)问题?

4

1 回答 1

1

我不确定您在考虑什么标准来将此构造标记为可疑。如果 bar 的值与 int 的大小(以位为单位)一样大,则显然有问题,但通常编译器不会知道这一点。从启发式的错误发现工具的角度来看,具有将可能的错误与正常结构区分开来的良好模式是避免过多误报(这使用户讨厌该工具并拒绝使用它)的关键。

我的 URL 中的开源工具将逻辑移位标记为大于类型大小的数字,但它主要是用于关键嵌入式软件的验证工具,如果您打算在 Linux 上使用它,需要做很多工作来适应它内核及其链接结构和其他困难。

于 2009-07-16T20:06:25.733 回答