2011-04-26 25 views
8

我們使用Parasoft C++test靜態分析我們的代碼。它具有代碼麻煩像下面這樣:Parasoft C++ test令人困惑的控制流分析

void foo(int* x) { 
    try { 
     bar(); 
    } catch(...) { 
     delete x; 
     throw; 
    } 

    *x; 
} 

報告警告說,在*x;行:

釋放的內存事後不得在任何情況下訪問

不知怎的,它得出的結論該控制流可以傳遞到catch(...)區塊,刪除x,通過throw;,並使其到*x;。我嘗試了throw std::exception("");和其他幾個人,得到了同樣的結果。 Parasoft當然知道異常並將它們合併到其控制流程中,因爲還有許多其他涉及異常檢查的測試。在這種情況下,它只是困惑,或者實際上有一些方法可以執行這個程序來同時擊中delete x;*x;

+0

它看起來像它變得困惑。 – 2011-04-26 20:37:36

+0

我想說它很困惑 - 但你應該問問Parasoft。我也會說,如果你有這樣的真實代碼,你就錯了。 – 2011-04-26 20:39:29

+0

你可以將'delete x;'提取成一個內聯方法嗎?或者Parasoft知道在那裏看看? – quamrana 2011-04-26 20:40:34

回答

0

也許這是一個愚蠢的建議,但是如果你爲了最後的目的而離開捕捉器,Parasoft會說什麼?即

void foo(int* x) 
    { 
    try 
    { 
    bar(); 
    *x; 
    } 
    catch(...) 
    { 
    delete x; 
    throw; 
    }  
    } 

我意識到,可能不適合報表和例外的所有組合的工作,例如,如果你有多個異常類型趕上與富的不同階段有不同的處理,但至少它可能會給你的開始一個解決方法,如果你真的想擺脫這個警告。

+0

這不是愚蠢的,可能就在旁邊這一點:) – sehe 2011-04-27 15:14:00

+1

如果它解決了這個問題,那麼它並不是真正的重點 - 儘管我確實傾向於僅僅忽略Parasoft的分析工具的明顯錯誤的結論。 – 2011-04-27 15:23:18

+0

我第二評論。如果您通過更改代碼開始解決誤報,您將引入錯誤。這可能是50次的一次或200次的一次。無關緊要:您花時間引入錯誤。 – 2011-04-27 20:27:06

2

所以這個工具是錯誤的(之前已經有人說過,我知道),並且我假設你不想要開啓警告。

我同意@Pascal的評論,重寫代碼只是爲了解決某些工具的限制是有點危險的。你可以做的就是禁用這個警告,只爲你目前有這個問題的文件。

然後,你有一個免費的構建開始,沒有一個工具告訴重寫現有的有效代碼。

對於新代碼,您將不得不採用該工具所瞭解的某種樣式。這不是一個問題,因爲這將成爲您目前正在使用的代碼,所以如果您需要稍微重寫它以避免警告,那麼這不是一個問題。

雖然正確,但現有的風格遠非理想。

我會推薦在auto_ptr's中存儲像x這樣的指針。如果auto_ptr的內容超出了範圍,它會自動刪除它的內容 - 除非你明確地將它從auto_ptr中取出。這在眼睛上要容易得多,並且很好地證明這個函數擁有指針的所有權。

void foo(auto_ptr<int> x) 
{ 
    bar(); 
    *x; 
} 

我希望ParaSoft將沒有這個代碼的問題。

0

快速更新:

1)上述的規則是不是在所有的流的分析規則。這就是說,在C++測試9.2.0及更高版本中,規則(ID MRM-31)得到了改進。在C++測試(ID:BD-RES-FREE)中也有相應的流程分析規則,它應該做你想做的事情。