Boost logo

Boost :

Subject: Re: [boost] [testing] Add a tester with hidden visibility
From: Niall Douglas (s_sourceforge_at_[hidden])
Date: 2015-05-07 13:13:39


On 7 May 2015 at 19:39, Andrey Semashev wrote:

> > It is a bad idea to dllexport templates as it greatly increases the
> > chance of an ODR violation biting you in the ass (e.g. two internal
> > private types with the same name). Nor is it ever necessary, as
> > template implementation is always header only. Just leave templates,
> > or any header implemented code, alone. Let them be compiled into a
> > local implementation for every ELF object. Remove anything you really
> > need to have exactly a single implementation of into a non-templated
> > base class which is dllexported.
>
> That's a very simplistic approach. In practice it is often needed to export a
> template specialization for different reasons: dependency hiding, compilation
> speedup, code size reduction, etc. Of course, there are complications and
> caveats but "just don't do it" is often not an answer.

Up until C++ 11 I really would say "just don't do it". The compiler
doesn't know not to instantiate dllexported templates and does so
anyway, so compilation speedup is zero. Marking templates with
dllexport means the linker must deal with a ton more symbols to match
up and remove because they aren't hidden, so you lose on link times
too. The only potential win is code size reduction, and given that
most compilers compile template instantiations into two variants,
inlined at point of use and extern, the latter rarely actually gets
used and is therefore thrown away by the linker anyway, so the gains
are usually not worth the significant added hassle and brittleness
for most libraries with most reasonably sized templates.

Since C++ 11 we have extern templates, and that finally makes
dllexporting template instantiations useful. I can see very
significant potential benefits especially to compile and link times
there, but a much superior implementation is to mark all common
instantiations extern template in the headers and to supply a
separate standalone library (without default hidden visibility) with
all the common instantiations in one place. So you would have a two
library solution there, one with with default hidden with the normal
code and common template instantiations marked extern, and a second
with default visible with the common template instantiations
supplied.

I hope that made sense. My point is, trying to do portable visibility
management for templates from within a single library is likely much
harder, much slower, and more brittle than a two library solution.

Niall

-- 
ned Productions Limited Consulting
http://www.nedproductions.biz/ 
http://ie.linkedin.com/in/nialldouglas/



Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk