3

Suppose you are using a template class in your application, like e.g. std::tuple (or std::shared_ptr, or whatever), and you have instantiations like this:

typedef std::tuple<Book,Library> BookLibrary;
typedef std::tuple<Book,Chapter,Reader> BookChapterReader;

And then you are using these instantiations in other templated classes, e.g. an std::map as member in a class:

class X
   {
   ...
   private:
      std::map<Library,BookChapterReader> m_data;
   };

Then the resulting PDB file will contain descriptions like this (seen with the DBH utility of the Microsoft Debugging Tools):

std::_Tree<std::_Tmap_traits<Library,std::tr1::tuple<Book,Chapter,Reader,std::tr1::_Nil,std::tr1::_Nil,std::tr1::_Nil,std::tr1::_Nil,std::tr1::_Nil,std::tr1::_Nil,std::tr1::_Nil>,std::less<Library>,std::allocator<std::pair<Library const ,std::tr1::tuple<Book,Chapter,Reader,std::tr1::_Nil,std::tr1::_Nil,std::tr1::_Nil,std::tr1::_Nil,std::tr1::_Nil,std::tr1::_Nil,std::tr1::_Nil> > >,0> >

If you have quite some of these constructions then the PDB file grows very quickly, until a moment where the linker just refuses to link your application (apparently, the PDB file has a limit of 1 GB).

A solution could be to create a subclass of the templated instantiation, like this:

class BookChapterReader : public std::tuple<Book,Chapter,Reader>
   {
   };

This will seriously shorten the symbols. The one mentioned above now is:

std::_Tree<std::_Tmap_traits<Library,BookChapterReader,std::less<Library>,std::allocator<std::pair<Library const ,BookChapterReader> >,0> >

However, by using inheritance we introduce the risk that one might add data to the inherited class, and we might need to introduce a virtual destructor (which I don't want here in this case).

It seems that C++ (or Visual Studio?) has a limitation:

  • If I just use a typedef, the symbols become much too large
  • If I use inheritance it might seem I want to extend the std::tuple, but I don't want to do this

Isn't there a cleaner way to 'rename' a template instatiation without using inheritance?

Patrick
  • 23,217
  • 12
  • 67
  • 130
  • I don't think VS2010 support it, and I also don't know how it's handled for the PDB "expansion", but otherwise you could try e.g. `using BookChapterReader = std::tuple;` – Some programmer dude Dec 09 '13 at 08:53
  • 3
    A type needs to have a unique name, so different TUs know that they are talking about the same thing. So your only chance to shorten debug symbols, is to create new/different types (note that typedef/using just creates aliases). – PlasmaHH Dec 09 '13 at 09:09
  • 1
    @JoachimPileborg `using X = foo;` is [equivalent](http://stackoverflow.com/q/10747810) to `typedef foo X;` so a difference would be surprising (but it doesn't cost much to try and see indeed). @Patrick Btw, what makes your problem worse is that VS2010 doesn't have a true support of C++11 and uses “`std::tr1::tuple`” for what should really be simply “`std::tuple`” (which I think VS2012 or later indeed uses). But that's not an answer, I know... – gx_ Dec 09 '13 at 11:07
  • @gx_, I know. the VS2010 implementation is even limited to 10 dimensions. That's why I use boost::fusion::vector and not std::tuple, but I wanted to keep the example simple enough. – Patrick Dec 09 '13 at 12:52

1 Answers1

1

Create your own version of both less and allocator implementations instead of relying on the default which have a very long name.

std::map< Library, BookChapterReader, CompareLibrary, MyAllocator > m_data;

The allocator class is super simple and so is the Compare functor.

egur
  • 7,830
  • 2
  • 27
  • 47
  • 1
    `std::less` is 18 characters. `CompareLibrary` is 14. Not much of a difference. – chris Dec 09 '13 at 09:16
  • @PlasmaHH: you forget that a custom class should be placed in a namespace; so you are looking at least at `X::Y`. – Matthieu M. Dec 09 '13 at 10:33
  • @MatthieuM.: It should also have a decent name, so ditch that namespace requirement and make stuff short. – PlasmaHH Dec 09 '13 at 10:45
  • The allocator is long and for some reason the 2nd template argument type didn't use the typedef. – egur Dec 09 '13 at 10:50
  • 1
    @PlasmaHH: Honestly, the only thing I can think of is to ditch MSVC until they implement decent support for types, like... using a `type -> id` mapping at the start of the PDB and only referring to the types by `id` afterward ? – Matthieu M. Dec 09 '13 at 17:44
  • @Matthieu, good suggestion. If I were Microsoft I would implement this; unfortunately, I'm not. – Patrick Dec 11 '13 at 08:08