在 C 代码中查找 "fallthroughs"
Finding "fallthroughs" in C code
在我正在开发的产品中发现了几个严重的错误,所有错误都与 switch 语句中的无意 "fall throughs" 有关。
现在,我想更进一步 - 我想检测大量 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;
}
我建议用更新的编译器编译你的代码只是为了检测那些(我知道你提到你不能为项目这样做但有时用其他东西编译它很有用,以便对事物有不同的看法) .
我的工作是一个(可怕的)旧版本的 GCC 编译我们的 "official" 代码和 clang 做一个虚拟编译只是为了有更好的静态分析。
如果您使用的是 GCC,则应使用 Wimplicit-fallthrough
compiler option 生成失败警告。您也可以使用 -Werror
(即针对此特定警告的 -Werror=implicit-fallthrough
。
我更喜欢使用 -Wextra
(其中包括此警告和许多其他警告),但如果这是一些大型遗留代码库,它可能会产生太多噪音。它是你应该争取的,以-Wextra -Wpedantic -Werror
通过构建。
如果您的编译器版本不支持这样的选项,也许您可以编写自己的正则表达式来匹配所有未以先前的 case
语句为前缀的 case
,尽管您必须小心确保正则表达式匹配所有出现,无论 formatting/comments.
例如,你可以使用这样的东西(这里是 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" 组的所有行。
在我正在开发的产品中发现了几个严重的错误,所有错误都与 switch 语句中的无意 "fall throughs" 有关。
现在,我想更进一步 - 我想检测大量 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;
}
我建议用更新的编译器编译你的代码只是为了检测那些(我知道你提到你不能为项目这样做但有时用其他东西编译它很有用,以便对事物有不同的看法) .
我的工作是一个(可怕的)旧版本的 GCC 编译我们的 "official" 代码和 clang 做一个虚拟编译只是为了有更好的静态分析。
如果您使用的是 GCC,则应使用 Wimplicit-fallthrough
compiler option 生成失败警告。您也可以使用 -Werror
(即针对此特定警告的 -Werror=implicit-fallthrough
。
我更喜欢使用 -Wextra
(其中包括此警告和许多其他警告),但如果这是一些大型遗留代码库,它可能会产生太多噪音。它是你应该争取的,以-Wextra -Wpedantic -Werror
通过构建。
如果您的编译器版本不支持这样的选项,也许您可以编写自己的正则表达式来匹配所有未以先前的 case
语句为前缀的 case
,尽管您必须小心确保正则表达式匹配所有出现,无论 formatting/comments.
例如,你可以使用这样的东西(这里是 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" 组的所有行。