我们正在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'的长度不长,但是作为一个小数值常量,默认为int。因此,即使bar的实际值从未超过16,也仍然
(1<<bar)
表达式将溢出并破坏整个计算。可能正确的解决方案:写1ULL代替。
是否有一个著名的编译器和编译器警告标志会指出这个(修订)问题?
最佳答案
我不确定您要标记的标准是什么
这种构造可疑。显然有
如果bar的值大于
一个int的大小(以位为单位),但通常是编译器
不会知道的。
从启发式错误发现工具的角度来看,
有良好的模式将可能的错误与
正常构造是避免过多错误的关键
正面(使用户讨厌该工具而拒绝
用它)。
我的网址中的“开源”工具将逻辑移位标记为大数
比类型的大小大,但主要是验证
关键嵌入式软件的工具,需要大量工作
如果您打算在Linux内核上使用它,请适当使用它
及其联系的结构和其他困难。
关于c - 使用编译器警告捕获常量1的左移溢出?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1139597/