2017-09-01 50 views
4

在我正在处理的产品中发现了几个令人讨厌的错误,所有这些错误都与switch语句中的无意中“跌倒”有关。在C代码中发现“穿透”

现在,我想更进一步 - 我希望检测大量C代码中的switch语句。 我只能使用Linux和gcc 5.6进行编译(所以没有叮当声或更新的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; 
    } 
+3

您应该研究术语* statical analysis *和* linter *。 –

+0

我做过了,它看起来很少涉及穿透。我知道最新的gcc中有一个开关,但我不能使用该版本的gcc。 – VividD

+4

你的两个例子都有“fall throughs” - 情况'0'落入情况'1'。无论如何,如果你想检测这样的事情,写一些解析你的源文件的代码,并尖叫是否符合你想要的条件。 C编译器通常不会诊断这些事情,因为代码是有效的 - 所以你编写代码来自己做。 – Peter

回答

2

我建议编译代码与较新的编译器只是为了检测这些(知道你提到你不能为项目做到这一点,但有时用别的东西来编译它有不同的观点)。

我的工作是一个GCC的旧版本,编译我们的“官方”代码和clang做一个虚拟编译只是为了有更好的静态分析。

+0

这也是一个非常合理的建议,使用新编译器的虚拟编译器可以作为外部linter。 – Groo

+0

我的目标架构中不存在新的gcc。 5.6是最新的。 @Groo – VividD

+0

@VividD你不需要针对你的目标架构进行编译,因为你只需要编译器提供的linting信息 –

3

如果您使用的是GCC,则应该使用Wimplicit-fallthrough compiler option来生成警告。您也可以使它成为使用-Werror(即-Werror=implicit-fallthrough这个特定的警告的错误。

我宁愿使用-Wextra(其中包括这和其他许多额外的警告),但如果这是一些大的遗留代码库,它可能会产生太多的噪音,这是应该争取什么,用-Wextra -Wpedantic -Werror通过构建。

如果你的编译版本不支持这样的选择,也许你可以写自己的正则表达式这将匹配所有case不是以前面的case声明为前缀,但您必须小心以确保正则表达式匹配所有oc currences,无论格式/评论。

例如,你可以使用这样的事情(在这里是一个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,或其他)脚本对你的文件夹,并转储所有线路,其中“突破”组被捕获。

+0

好,但'-Wimplicit-fallthrough'只在最近版本的GCC –

+0

@BasileStarynkevitch:你是对的,我注意到OP使用的是gcc 5.4。我想一个正则表达式*可能会诀窍,当我得到一个空闲时刻后,我会更新答案。 – Groo