http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53596

--- Comment #3 from kim.walisch at gmail dot com 2012-06-07 07:31:41 UTC ---
Hi, thanks for your answer but I still think it is a bug. Here are my reasons:

1) You mention that Clang also warns for my example but this seems to be a bug
in Clang, see
http://lists.cs.uiuc.edu/pipermail/llvmbugs/2012-March/022451.html

2) Herb Sutter wrote a Guru of the Week (GotW) article on this topic
(http://www.gotw.ca/publications/mill18.htm), it says: 

Guideline #4: A base class destructor should be either public and virtual, or
protected and nonvirtual.

3) If I modify 'virtual void foo()' to 'void foo()' in my previous example the
warning vanishes, this makes no sense.

terminal log:

$ g++-4.7 -Wall test2.cpp 
$

/////////////////////////////////////////////////////////////////
// file: test2.cpp

#include <iostream>

class Base {
protected:
  ~Base() { }
};

class Derived : public Base {
public:
  void foo() { std::cout << "Derived::foo()"      << std::endl; }
  ~Derived() { std::cout << "Derived::~Derived()" << std::endl; }
};

int main() {
  Derived* derived = new Derived();
  derived->foo();
  delete derived; // correct, no warning!
  return 0;
}

/////////////////////////////////////////////////////////////////

4) In your MoreDerived example you can make the Derived dtor virtual, this way
the protected non-virtual Base destructor is absolutely valid.

/////////////////////////////////////////////////////////////////
// file: test3.cpp

class Base {
public:
  virtual void foo() = 0;
protected:
  ~Base() { }
};

class Derived : public Base {
public:
  virtual void foo() { }
  virtual ~Derived() { }
};

class MoreDerived : public Derived {
public:
  ~MoreDerived() { }
};

int main() {
  Derived* morederived = new MoreDerived();
  morederived->foo();
  delete morederived; // no warning, virtual Derived dtor
  return 0;
}

/////////////////////////////////////////////////////////////////

Reply via email to