2010-08-13 67 views
5

我期待能夠檢測以嵌套的方式有序函數調用對的工具,如下圖所示:如何檢測正確的函數調用對

f() // depth 0 
    f() //depth 1 
    g() 
g() 

在通話f()的每個深度必須有g()通話形成函數調用對。這在臨界區進入和退出時尤爲重要。

+0

在從'f'返回之前,爲什麼不從'f'調用'g'? – Chubsdad 2010-08-14 01:12:21

+0

@chubsdad:因爲'f()'和'g()'之間存在代碼,所以可能認爲是'lock()'和'unlock()',而不是'f()'和'g()'。 – caf 2010-08-14 07:32:14

回答

11

在C++中,一個選項是將調用包裝到f()g()的類的構造函數和析構函數中,並通過實例化該類的實例來調用這些函數。例如,

struct FAndGCaller 
{ 
    FAndGCaller() { f(); } 
    ~FAndGCaller() { g(); } 
}; 

然後可以在任何範圍內塊中使用,像這樣:

{ 
    FAndGCaller call_f_then_later_g; // calls f() 

} // calls g() 

很顯然,在實際的代碼,你會希望更適當命名的東西,而且通常會只是想在構造函數和析構函數體中具有f()g()的內容,而不是在單獨的函數中。

這個範圍綁定資源管理(SBRM,或更常被稱爲資源獲取是初始化,RAII)的習慣用法很常見。

+0

如果f()拋出一個錯誤,g()永遠不會被調用,但是類/結構的資源將被釋放。 – 2010-08-14 12:14:28

+1

@ PC2st:是的,但如果'g()'做與f()'做相反的操作(或「撤銷」),那麼如果'f()'拋出一個你不想調用的異常'g ()'。 – 2010-08-14 13:30:02

0

掃描代碼(這是困難的部分),每次看到f()的調用時,都會增加一個計數器。每次看到g()的調用時,都會減少計數器。最後,計數器應該回到零。如果它發生負面情況,那也是一個問題(你有一個g()的電話,並且之前沒有與f()匹配的電話)。

準確地掃描代碼雖然很難 - 用C和(特別是)C++編寫代碼來理解源代碼很難極其。不客氣,我不知道這個特定工作的現有工具。毫無疑問,你可以讓叮噹(舉一個例子)來做,但是它比完全依靠自己做起來要容易得多,但它仍然不是微不足道的。

+0

這種方法的問題是它不檢查f()和g()的級別 - 它會確保你有合適的數量,但它不能保證你讓他們在同一層次上彼此鏡像。此外,OP要求使用工具,而不是查看代碼的方式。 – 2010-08-13 21:07:59

+0

@adam_0:至少根據他顯示的代碼,通過調用f()和g()來定義級別。如果還有更多的情況,他可能需要告訴我們要得到一個有意義的答案是什麼。我懷疑現在有什麼工具可以完全滿足他的要求,所以我試圖告訴他如何構建一個。 – 2010-08-13 21:11:41

+0

除clang之外的另一種選擇是使用Qt-Creator附帶的諾基亞C++解析器庫。它是跨平臺的,自包含的(libCPlusPlus。{so,dll}),並且不難開始,但它仍然不是微不足道的。這本書寫得很好,得到很好的支持,因爲它已經用於他們的許多不同項目。 – 2010-08-13 21:11:50

2

爲此,您可能會濫用for -loop。

#define SAVETHEDAY for (bool seen = ((void)f(), true); seen; seen = ((void)g(), false)) 

逗號操作符總是讓你的功能f可以在相關的語句之前和之後g執行。 E.g

SAVETHEDAY { 

    SAVETHEDAY { 

    } 
} 

優點:

  • 使嵌套層次清晰。
  • 適用於C++和C99。
  • for -loop將由 編譯器優化掉 。

缺點:

  • 你可能有意外的驚喜與 breakreturncontinue 塊裏面,所以g可能無法在這種情況下調用。
  • 對於C++,這不是對一個 throw內部安全,再次g可能不叫
  • 將在被許多人皺起了眉頭,因爲是在某種擴展語言(S)。
  • 將在被許多人 尤其是對於C++自認爲隱藏代碼通常 這樣的宏來皺起了眉頭都 認爲是邪惡的

continue問題可以通過一個更加聰明的做事修復。 前兩個cons可以通過在構造函數和析構函數中使用和g作爲for-變量的虛擬類型在C++中繞過。

+0

令人震驚的切肉刀,但如此無用... – Joshua 2010-08-13 21:54:51

+1

@Joshua:我的英語可能不夠好,不知道*切肉刀*只是一個錯字,或者如果你給它更深的含義。但無論如何,對我來說,這並不是無用的,因爲我使用它「每天」,這是一個非常方便的習慣用來保護例如關鍵部分或確保一些初始化代碼只運行一次。 – 2010-08-14 05:55:08

+0

這只是一個錯字。我經常做那個。 – Joshua 2010-08-16 15:10:23

相關問題