|
Boost : |
From: Vladimir Prus (ghost_at_[hidden])
Date: 2007-05-06 02:18:42
David Abrahams wrote:
>
> on Sat May 05 2007, Jeff Garland <jeff-AT-crystalclearsoftware.com> wrote:
>
>> Jonathan Franklin wrote:
>>
>>> For example, GCC has a
>>>> warning about a derived class whose base doesn't have a virtual dtor.
>>>> It's actually *impossible* (not just inefficient or convoluted) to
>>>> implement is_polymorphic without generating that warning.
>>>
>>>
>>> Interesting. I'm obviously flaunting my ignorance, but I didn't realize
>>> that inheriting from a class sans virtual dtor was ever a Good Thing.
>>> I'll have to read up on the issues WRT is_polymorphic.
>>
>> I find inheriting without virtual functions quite useful. The main
>> reason for
>> the virtual destructor rule goes back to Scott Meyers Effective C++. He
>> points out that if you have Base <-- Derived and you call delete Base*
>> the destructor of Derived is not called. In general, it's hard to ensure
>> your derived classes won't need the destructor called and hence the rule.
>> However, if Derived happens to have a trivial/empty destructor then,
>> really there's no reason to call it.
>
> is_polymorphic doesn't do anything so evil as to invoke UB, because
> the type created is only used to compute the compile-time value of the
> is_polymorphic predicate, and is never allocated on the heap or
> delete'd.
>
> Anyway, there are many other legitimate idioms that also don't unvoke
> UB, such as CRTP. Sometimes the existence of a base class is an
> implementation detail. The base class isn't documented as such, and
> there's nothing useful clients can do with it, so they never end up
> touching anything but the complete object. Inheritance is often a
> crucial tool in creating lightweight objects that shouldn't have any
> virtual functions.
And what wrong does gcc do with CRTP? As far I can tell, if you use -Wall,
the warning is only emitted for class that has virtual functions and
non-virtual destructor. For that case, adding virtual destructor is cheap,
as there's already vtable, and seem to be good thing to do.
I've tried this example with is_polymorphic:
#include <boost/type_traits/is_polymorphic.hpp>
struct C1 { int i; };
struct C2 { virtual void foo() {} };
int main()
{
return boost::is_polymorphic<C1>::value
+ boost::is_polymorphic<C2>::value;
}
And gcc warns. Desprite warning being overly wordly, it basically
warns that C2 has virtual function but lacks virtual destructor.
Adding virtual destructor to C2 makes the example compile without
warning.
Or maybe you have -Weffc++ option in mind? That, indeed, causes
warning to be emitted for all base classes without virtual
destructors. However, nobody uses that option, precisely because
it gives pages and pages of warnings on legitimate code, including
standard library.
- Volodya
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk