在我正在处理的产品中发现了几个令人讨厌的错误,这些错误都与转换语句中无意中的“漏洞”有关。
现在,我想超越一步 - 我想在大量的C代码中检测switch语句。 我只能使用Linux和gcc 5.6进行编译(所以没有clang或更新的gcc;这是因为我们项目的目标架构不存在更新的gcc。)
这是一个没有失败的代码:
switch(m_loadAnimSubCt){
case 0:
case 1:
// Do something
break;
case 2:
case 3:
case 4:
// Do something
break;
}
这是一个带有漏洞的代码:
switch(m_loadAnimSubCt){
case 0:
case 1:
// Do something but fall through to the other cases
// after doing it.
case 2:
case 3:
case 4:
// Do something else.
break;
}
答案 0 :(得分:3)
我建议用一个较新的编译器编译你的代码只是为了检测那些(我知道你提到你不能为这个项目做那个但是有时用其他东西编译它以对事物有不同的看法)。 / p>
我在工作中得到的是一个(可怕的)旧版本的GCC编译我们的“官方”代码,并且为了更好的静态分析而进行虚拟编译。
答案 1 :(得分:3)
如果您使用GCC,则应使用Wimplicit-fallthrough
compiler option生成针对坠落的警告。您也可以使用-Werror
(即-Werror=implicit-fallthrough
针对此特定警告将其变为错误。
我更喜欢使用-Wextra
(其中包括此警告和许多其他警告),但如果这是一些大型遗留代码库,则可能会产生太多噪音。 是你应该努力的目标,用-Wextra -Wpedantic -Werror
传递构建。
如果你的编译器版本不支持这样的选项,也许你可以编写自己的正则表达式,它匹配前面的case
语句没有前缀的所有case
,尽管你必须要小心确保正则表达式匹配所有匹配项,无论格式/注释如何。
例如,你可以使用这样的东西(这里是demo):
(?# match any 'case' following 'break;', ':' or '{' into a non-capturing group)
(?# then match the remaining 'case' into a named "fallthrough" group)
(?:(break;|:|{)[\r\n\s]*case) | (?<fallthrough>case)
因此,您可以针对您的文件夹运行perl(或python或其他)脚本,并转储捕获“fallthrough”组的所有行。