2011-04-25 32 views
7

在C++代碼中找到未實例化模板的最佳方法是什麼?在C++代碼中查找非實例化模板

我有一個大量使用模板的代碼庫。 當然,我們要確保測試覆蓋率很高。 對於所有使用的代碼,這可以很好地使用gcov

但是,未使用的模板被報告爲gcov不可執行。

一些google搜索後,似乎沒有辦法強迫g++發出代碼爲這些模板(這是唯一合乎邏輯的,編譯器應該怎麼猜到的任何類型?) 似乎也沒有辦法讓gcov將未被證實的模板代碼識別爲可運行代碼。

是否有任何「開箱即用」的功能允許我擴充由GCC -ftest-coverage -fprofile-arcs儀器生成的文件?通過gcov option documentation of GCC,將整個模板函數體標記爲一個塊可能就足夠了,因爲執行永遠不會結束。

編輯(背景信息):我正在研究僅標題模板庫。 我的目標是找到未使用/未經測試的功能。

我知道代碼覆蓋率有缺陷,但發現無實際代碼是朝着更好的測試代碼邁出的非常重要的一步。 目前,我們將檢查點宏放在每個函數的開頭。 在測試模式下,它們擴展爲將一對(file, line)插入全局通過的檢查點集的代碼。 運行測試後,我們手動讀取所有文件,並將所達到的檢查點與所有可用檢查點的集合進行比較。

查找未經實例化的代碼很重要,例如,由於C++模板優先級不直觀的行爲,因此可能存在讀者甚至作者期望使用的死代碼。

+0

您的意思是從不爲任何類型實例化的模板類/結構體/函數? – Xeo 2011-04-25 21:28:05

+0

@Xeo:是的,這就是我的意思。 – Manuel 2011-04-25 21:28:45

+2

我不確定你問的問題對我有意義。編譯器僅爲所使用的類型實例化模板。如果某些給定類型從未用於該模板,那麼該特定實例化將不存在於目標代碼級別。 – greatwolf 2011-04-25 21:31:59

回答

1

好的,因爲我對GCC不是很熟悉,所以這裏是一個乏味且非常耗時的解決方案,但至少可以工作! :)
這個測試依賴於一個事實,即在模板代碼一些錯誤未檢測到實際的實例,即當沒有實際的模板參數存在依賴名稱:

template<class T> 
struct Example{ 
    typedef typename T::_123344_non_existent_type instantiation_test; 
}; 

添加這樣一個typedef到你擁有的每個模板,然後編譯。從每個結構/類/函數中刪除它,編譯器顯示錯誤,並且每個模板仍然包含這樣的typedef,當代碼最終編譯時永遠不會被實例化。或者你是不幸的,有些類型可以定義這樣的_123344_non_existent_type,但我會欺騙那個負責這個的同事。 ;)

+0

儘管可行,但這與維護上述我在編輯中描述的檢查點宏方法的工作密切相關。 – Manuel 2011-04-25 21:47:43

+0

@曼紐爾:是的,我在第一句話中這麼說。 ;)對不起,但我在編輯問題時不在線。 ^^ – Xeo 2011-04-26 06:41:08

+0

@Manuel:實際上它更糟糕,如果你重新測試你的測試套件,你需要從頭開始,因爲你之前已經從那些工作的案例中刪除了'typedef'。 – 2011-04-26 08:31:37

2

我認爲我們的C++ Test Coverage工具(不是基於GCC)從你的角度正確地做到了這一點。

它在之前編譯源代碼編譯器看到它;無論模板是否被使用,模板中的代碼都會得到「覆蓋探測器」。該工具的測試覆蓋顯示部分知道所有探針的位置;如果模板代碼沒有被實例化,那麼顯然不能執行那些會被報告的內容。您不必執行任何「自定義」宏插入或其他呃BS。

缺點是,如果你有一個由幾種不同類型參數化的模板,並且爲不同的實例化類型執行模板方法m1和m2,那麼你對m1和m2的覆蓋率將爲100%(畢竟,模板)。目前尚不清楚這是否糟糕;只是這是如何解釋。