2017-09-01 51 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