* Jozef Matula:
> diff -ru cryptopp/cryptlib.h cryptopp.fixed/cryptlib.h
> --- cryptopp/cryptlib.h 2005-07-13 04:19:10.000000000 +0200
> +++ cryptopp.fixed/cryptlib.h 2005-07-23 14:30:36.000000000 +0200
> @@ -521,6 +521,8 @@
> class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE HashTransformation : public Algorithm
> {
> public:
> + virtual ~HashTransformation() { }
> +
This change just switches key method. It also means that the vtable
is now emitted in each translation unit, which increases code size
in the dynamic linking case.
In other words, the underlying problem is not fixed. Below is an
excerpt of a message I sent to another list member. The example is
based on <http://lists.debian.org/debian-devel/2005/07/msg01274.html>.
Yes, the "extern tempalte" construct, which is currently used (via
preprocessor #defines) by crypto++. So this example is more exact:
First translation unit ("interface"/header file):
// -[begin]-----------------------------------------------------------
template <int I>
struct Foo
{
virtual ~Foo();
};
extern template struct Foo<5>;
// -[end]-------------------------------------------------------------
Second translation unit ("implementation"):
// -[begin]-----------------------------------------------------------
template <int I>
struct Foo
{
virtual ~Foo();
};
template struct Foo<5>;
template <int I>
Foo<I>::~Foo()
{
}
// -[end]-------------------------------------------------------------
It should be safe to transform the second case to:
// -[begin]-----------------------------------------------------------
template <int I>
struct Foo
{
virtual ~Foo();
};
extern template struct Foo<5>;
template <int I>
Foo<I>::~Foo()
{
}
template struct Foo<5>;
// -[end]-------------------------------------------------------------
In other words, move the explicit instantiation to a point were all
members have been defined, including the key method which controls
vtable emission.