6

I have a lot of template code. Since bad template code does not throw a compiler error unless it is compiled, is there any way I can check which template functions the compiler actually 'compiled' and which were ignored altogether?

EDIT 2:

If a particular class template or function template is instantiated once, for any parameter types, then that is OK. I want the list of function/class templates that were never instantiated in any form.

One particular example is the following. They are two distinct template functions, and I would like to know if either or both is never instantiated.

template <typename T_InputItr, typename T_Distance>
void advance( T_InputItr& aItr, T_Distance aN, bidirectional_iterator_tag )

template <typename T_InputItr, typename T_Distance>
void advance( T_InputItr& aItr, T_Distance aN, random_access_iterator_tag )

EDIT: Currently, for classes, I instantiate them in the .cpp file manually like this:

template TClass<int>;

for all the types I am interested in. That's well and good. But that is if I remember to do that. Sometimes I need to write a lot of small template classes/functions where I forget to instantiate some of the function/class templates manually and find out later down the road. I would like the compiler to tell me that.

Alternatively, if I could get the list of function/class templates that were instantiated (for any parameter), then I could compare that to the full list which I might grep for in the code.

Another benefit would be to 'test' which methods were compiled in a template class that uses type traits to selectively compile out certain functions. I want to be certain my logic for selecting the correct functions is correct before moving on.

Samaursa
  • 16,527
  • 21
  • 89
  • 160
  • And what would you do if you could check that? – Jon Jan 20 '12 at 01:27
  • @Jon: I would test it by manually instantiating it with dummy types to make sure its syntax is correct, at least for the types that I know it can take. – Samaursa Jan 20 '12 at 01:28
  • So there's your answer: make a test project where you invoke *all* templated functions with *all* types you know they can take. If the project does not compile you have a problem. :) – Jon Jan 20 '12 at 01:31
  • Do you want to force it to compile all the templates for the types you are interested in? Or instead do you want to simple discover which ones were compiled? I imagine you really want the former. If the latter is the solution, then what is the problem it's supposed to solve!? – Aaron McDaid Jan 20 '12 at 01:31
  • @Jon: Haha, well, that is exactly why I am asking this. As humans, we tend to miss things. When was the last time you counted how many classes you have in your program :P The compiler knows however. I was hoping it would help me in this case as well. – Samaursa Jan 20 '12 at 01:33
  • Make your compiler generate assembly code out of your C++ code and study it. – Alexey Frunze Jan 20 '12 at 01:35
  • @Alex: I hope that's a joke :P – Samaursa Jan 20 '12 at 01:36
  • @Samaursa, can you take a step back and tell us what you really want to do here? If you could get this list, what would you do with it? Are you interested in making sure this list includes your target list of types? Or are you interesting in making sure this list *does not* include types except if they are on your list? Or both? (If so, then we can help clarify your question, and maybe answer it for you.) – Aaron McDaid Jan 20 '12 at 01:37
  • @Samaursa: Why? It once helped me figure out what some heavily templated code actually did. That was with msvc++. – Alexey Frunze Jan 20 '12 at 01:39
  • I'm still quite confused. Is your goal to see which *class templates* were instantiated (at least once)? Have many different *class templates* are you dealing with? And how many types are passed to each template? – Aaron McDaid Jan 20 '12 at 01:50
  • @AaronMcDaid: Let me know if you would like to join this room for a discussion: http://chat.stackoverflow.com/rooms/6873/check-templates – Samaursa Jan 20 '12 at 02:02
  • Good idea, @Samaursa . I'll be there for the next few minutes at least. – Aaron McDaid Jan 20 '12 at 02:04

3 Answers3

2

Given that you are using MSVC 2008, you can do this by generating a linker map file and searching for all the instantiations of that function or inspecting the .pdb via DIA. You'll want to disable COMDAT folding with the linker flag /OPT:NOICF so that you can find functions that happen to compile to the same assembly.

MSN
  • 53,214
  • 7
  • 75
  • 105
1

Someone mentioned how "everything can be solved by adding a level of indirection" - you can add a static assert to each function and watch the compilation fail:

template <typename T>
struct Asserter
{
  static const bool value = false;
};

template <typename T>
struct Foo
{
  void foo()
  {
    static_assert(Asserter<T>::value, "Foo::foo() is being compiled.");
  }
  void bar()
  {
    static_assert(Asserter<T>::value, "Foo::bar() is being compiled.");
  }
};

int main()
{
  Foo<int> f;
  //f.foo();  // static assertion!
}

If you don't want compilation to break at each step, you can instead emit a Boost static warning, or something with a similar effect.

Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
  • I ended up going with this solution, wrapping the asserts with macros that do nothing with a certain preprocessor. – Samaursa Mar 08 '12 at 17:10
  • "1 level of indirection" means that additional template instantiation (i.e. `Asserter` which gets instantiated when `Asserter::value` is evaluated)? It is interesting that it works, any idea why it works? – HCSF Nov 18 '21 at 03:29
0

You can run your executable through a static analysis tool after compilation provided you have setup your compiler to include the proper symbol tables ... that will show all the instantiated classes along with their template arguments. Here is a link to a list of tools that can be used for static code analysis.

Jason
  • 31,834
  • 7
  • 59
  • 78