2011-04-25 48 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%(毕竟,模板)。目前尚不清楚这是否糟糕;只是这是如何解释。