instantiated templates in C++ code

What is the best way to find uninstantiated templates in C++ Code?

I have a code base that heavily uses templates. Of course, we want to make sure that the test coverage is high. For all used code, this works very well using gcov .

However, unused templates are reported as non-executable by gcov .

After some googling, it appears that there is no way to force g++ to emit code for these templates (which is only logical, how should the compiler guess any types?) It also appears that there is no way to make gcov recognize the uninstantiated template code as runnable code.

Is there anything "out of the box" that allows me to augment the files generated by the GCC -ftest-coverage -fprofile-arcs instrumentation? By the gcov option documentation of GCC, it would probably be enough to mark the whole template function body as one block since execution will never end up there.

EDIT (background information): I'm working on a header-only template library. My aim here is to find unused/untested functions.

I know that code coverage is flawed but finding uninstantiated code is a very important step towards better tested code. Currently, we are putting checkpoint macros at the beginning of each function. In testing mode, they expand to code that inserts a pair of (file, line) into a global set of passed checkpoints. After running the tests, we manually read all files and compare the reached checkpoints with the set of all available checkpoints.

Finding uninstantiated code is important, for example, because of unintuitive C++ template precedence behaviour, there might be dead code somewhere that the reader or even the author would expect to be used.


I think our C++ Test Coverage tool (not GCC-based) does this correctly from your point of view.

It instruments the source code before the compiler sees it; code inside templates get "coverage probes" regardless of whether the template gets used or not. The test coverage display portion of the tool knows where all the probes are; if the template code isn't instantiated, it clearly can't be executed that's what will get reported. You don't have to do any "custom" macro insertion or other, er, BS.

The downside is that if you have a template parameterized by several different types, and template method m1 and m2 are executed for different instantiated types, your coverage for m1 and m2 will be 100% (after all, you executed the instrumented template). It isn't clear this is bad; just that it is how this is interpreted.


Okay, since I'm not very versed with GCC, here's a tedious and very time-taking solution, but atleast it works! :)
This test relies on the fact, that some errors in template code aren't detected until actual instantiation, ie when dependant names don't actually exist in the template parameter:

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

Add such a typedef to every template you have, then compile. Remove it from every struct/class/function the compiler displays an error for and every template that still contains such a typedef when the code finally compiles never gets instantiated. Or you're unlucky and some types do define such a _123344_non_existent_type , though I'd lynch the coworker that is responsible for that. ;)

链接地址: http://www.djcxy.com/p/6476.html

上一篇: 如何获得最大数量 列使用POI填充到XLSX文件中?

下一篇: 在C ++代码中实例化模板