views:

706

answers:

6

I would like to debug some templated code to understand it better.
Unfortunately I'm new to template metaprogramming and it IS hard for me to get in.

When I try to output the preprocessed source files I get 125 000 lines of code :/

So is there a way I can see the generated Code? (The library I'm using is SeqAn)

+13  A: 

No it isn't. The preprocessor has nothing to do with template processing, which is performed by the compiler. Templates do not generate C++ code, any more than a function call does - they are an integral part of the C++ language itself.

anon
While this is generally true, it's in theory also true for the preprocessor. In practice the easiest implementation is to generate C++-like code as the output of the preprocessor stage, but not for template instantiations. The reverse would be unreasonably hard but not technically impossible. The main problem is in name lookups, and the compiler could generate unique names during template instantiations.
MSalters
To be honest you still can use the debugger to show the calculated type if you instantiate it. I made an example how to use Visual C++. I used it for my meta-programs very often.
ovanes
+2  A: 

Template Metaprogramming is a generic programming technique that uses extremely early binding. The compiler acts as an interpreter or a "virtual computer" that emits the instructions that make up the final program.

adatapost
+1  A: 

This is potentially the answer to your question:

http://stackoverflow.com/questions/1139793/c-template-preprocessor-tool

Seems to have satisfied the last person who asked - though I can't imagine why! The output of a C++ compiler in C is usually pretty unreadable, because it isn't intended to be an aid to understanding, merely a kind of portable assembly language.

Daniel Earwicker
A: 

Hi *,

at general it is not possible to output the entire code. But what I found extremely interesting, is the ability to use Visual C++ debugger to show you the type. Take that simple meta-program:

template<class Head, class Tail>
struct type_list
{
  typedef Head head;
  typedef Tail tail;
};

struct null_type
{};

template<class List>
struct list_head
{
  typedef typename List::head head;
};

template<class List>
struct list_tail
{
  typedef typename List::tail tail;
};

template<class List>
struct list_length
{
  static const size_t length = 1+list_length< typename list_tail<List>::tail >::length;
};

template<>
struct list_length<null_type>
{
  static const size_t length = 0;
};


int main()
{
  typedef 
    type_list
    < int
    , type_list
      < double
      , type_list
        < char
        , null_type
        >
      >
    >       my_types;

  my_types test1;

  size_t length=list_length<my_types>::length;

  list_head<list_tail<list_tail<my_types>::tail>::tail>::head test2;

}

I just instantiated my meta-types. These are still empty C++ class instances which are at least 1 byte long. Now I can put a breakpoint after the last instantiation of test2 and see, which types/values length, test1 and test2 are of:

Here is what the debugger shows:

length  3 unsigned int
test1   {...} type_list<int,type_list<double,type_list<char,null_type> > >
test2   -52 'Ì' char

Now you you know the head returned you a character, your list contains int, double, char and is terminated by null_type.

That helped me a lot. Sometimes you need to copy the really messy type to a text editor and format it to a readable form, but that gives you the possibility to trace what is inside and how it is calculated.

Hope that helps,
Ovanes

ovanes
+4  A: 

Nope, in general, it can't be done. Templates are simply part of the C++ language, they're not a separate preprocessor, so they don't generate C++ code.

The usual solution is to sprinkle your code with static asserts and other tests to verify that the right templates get instantiated in the right ways.

Once you start getting lost in your metaprogramming, this simple trick can help you determine which type a template parameter really is:

// given a variable t of an unknown type T
int*** i = t;

When the compiler encounters this, it'll print out a nice and simple error message, "Can not convert <long, detailed typename> to int***", allowing you to easily verify that the template parameter T is actually the type you think it should be.

jalf
+2  A: 

Check my publication on C++ template metaprogram debugging:

http://gsd.web.elte.hu/contents/articles/gpce06.pdf

From page 6 you can see how it works. For specific purposes you won't need the whole toolchain, it can be done by hand.

I have put together a Visual C++ add-in where you could place breakpoints etc. but it was rather a proof of concept than a tool for every day use.

We have been working on a graphical frontend that shows all the instantiations, allows debugging, profiling. Unfortunately we cannot promise any publish date for that tool, as we do it in our quite limited free time.

jmihalicza
Looks interesting!
j_random_hacker