I know I'm late in the discussion, nevertheless my experience says that the compiler behaves differently when facing an empty destructor compared to a compiler generated one. At least this is the case with MSVC++ 8.0 (2005) and MSVC++ 9.0 (2008).
When looking at the generated assembly for some code making use of expression templates, I realized that in release mode, the call to my BinaryVectorExpression operator + (const Vector& lhs, const Vector& rhs)
was never inlined. (please don't pay attention to the exact types and operator signature).
To further diagnose the problem, I enabled the various Compiler Warnings That Are Off by Default. The C4714 warning is particularly interesting. It is emitted by the compiler when a function marked with __forceinline
doesn't get inlined nonetheless.
I enabled the C4714 warning and I marked the operator with __forceinline
and I could verify the compiler reports it was unable to inline the call to the operator.
Among the reasons described in the documentation, the compiler fails to inline a function marked with __forceinline
for:
Functions returning an unwindable object by value when -GX/EHs/EHa is on
This is the case of my BinaryVectorExpression operator + (const Vector& lhs, const Vector& rhs)
. BinaryVectorExpression
is returned by value and even though its destructor is empty, it makes this return value being considered as an unwindable object. Adding throw ()
to the destructor didn't help the compiler and I avoid using exception specifications anyway. Commenting out the empty destructor let the compiler fully inline the code.
The take-away is that from now, in every class, I write commented out empty destructors to let humans know the destructor does nothing on purpose, the very same way people comment out the empty exception specification `/* throw() */ to indicate that the destructor cannot throw.
//~Foo() /* throw() */ {}
Hope that helps.