This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: Proposal for improvement to C++ warnings


>> Gcc 2.95 for C++ warns when a class inherits from a base class with a
>> non-virtual destructor.
> 
> More exactly, it warns if a class has virtual member functions, but a
> non-virtual destructor.

That's not the warning to which I am referring.

----
// Suggestion of William E. Kempf and Wil Evers forwarded by Scott Meyers.

template <typename Arg1, typename Arg2, typename Result>
struct my_binary_function {
	typedef Arg1 first_argument_type;
	typedef Arg2 second_argument_type;
	typedef Result result_type;

protected:
	~my_binary_function() {}
};

template <typename Pair1, typename Pair2, typename Result>
struct my_less_1st : public my_binary_function<Pair1, Pair2, Result> {
    bool operator()(const Pair1 &a, const Pair2 &b) const
	 	{ return a.first < b.first; }
}; 

int main() { my_less_1st<int, int, int> fred; return 0; }
----

For the preceeding code, -Weffc++ enables the following warning.

----
main.cc: In instantiation of `less_1st<int,int,int>':
main.cc:17:   instantiated from here
main.cc:15: warning: base class `struct rbinary_function<int,int,int>'
  has a non-virtual destructor
----

>> I propose that gcc warn only when a class publicly
>> inherits from a base class with a public non-virtual destructor.
>>
>> The warning exists to prevent the deletion of a child class through a
>> pointer to a parent with a non-virtual destructor.  This results in
>> undefined behavior, according to The Standard.  
>
> I propose that gcc warn only if delete is invoked on a pointer to such a
> class.

Warnings exist to help developers avoid writing dangerous code.  In general, a
library developed with such a policy would be dangerous to use on a platform
without the warning enabled.

>> Private and protected inheritance from a base class with a non-virtual
>> destructor do not introduce the danger motivating this warning.
> 
> Are you sure?

In the absence of explicit casts to a private base class, I'm quite confident.
The current warning is broad enough to be generated for well-written code.
See the code I quoted, above.  This approach prevents deletion through a
pointer to the base class.  Using private inheritance accomplishes the same
thing.  This prevents handling the object by a reference or pointer to its
base class, unless an explicit cast is used.  The case of a non-virtual base
class destructor and protected inheritance is debatable.  A child of the child
could get into trouble with this one.  I suppose it would be better to revise
my proposal to the following:

  I propose that gcc warn only when a class uses public or protected
  inheritance from a base class with a public non-virtual destructor.

Anyway, a table of the interesting combinations follows.  I'm interested in
your comments, as long as they aren't sarcastic.

                  public base class destructor

Inheritance   virtual base constructor         non-virtual
private           safe, no warning         * safe,      gcc warns
protected         safe, no warning           debatable, gcc warns
public            safe, no warning           dangerous, gcc warns

                  protected base class destructor

Inheritance   virtual base constructor         non-virtual
private           safe, no warning         * safe, gcc warns
protected         safe, no warning         * safe, gcc warns
public            safe, no warning         * safe, gcc warns

-Robert Dick-


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]