public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c++/15505] New: pure virtual destructor not overloaded, but accepted
@ 2004-05-18 15:32 b dot perschbacher at att dot net
  2004-05-18 15:33 ` [Bug c++/15505] " b dot perschbacher at att dot net
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: b dot perschbacher at att dot net @ 2004-05-18 15:32 UTC (permalink / raw)
  To: gcc-bugs

When declaring a pure virtual destructor in a base class the complier will allow
a sub class to be created without having to define an implementation of a
destructor. However, linker errors are thrown when the references to the
destructors can't be found. This should not make it to the linker but instead be
caught like all other missing implementations of pure virtuals. 

the command g++ -v returned:
Reading specs from /usr/lib/gcc-lib/i386-redhat-linux/3.2.2/specs
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man
--infodir=/usr/share/info --enable-shared --enable-threads=posix
--disable-checking --with-system-zlib --enable-__cxa_atexit --host=i386-redhat-linux
Thread model: posix
gcc version 3.2.2 20030222 (Red Hat Linux 3.2.2-5)

I am using redhat 9.0 with the kernal listed above (I guess, this machine is
maitained by my company) with dual xeon processors.

some code to reproduce this bug:
#include <iostream>

using namespace std;

class base {
  public:
    base(void){
      cout << "Base default constructor." << endl << flush;
    }
    virtual ~base(void) = 0;
};

class base2 {
  public:
    base2(void){
      cout << "Base2 default constructor." << endl << flush;
    }
    virtual ~base2(void){};
};

class sub : public base {
  public:
    sub(void){
      cout << "Sub default constructor." << endl << flush;
    }
};

class sub2 : public base, public base2 {
  public:
    sub(void){
      cout << "Sub default constructor." << endl << flush;
    }
};

int main(void){
  sub subby;
  sub2 subby2;
  return 0;
}

//------------------------------------------------------------------------------

note the fact that it seems to be looking for the base destructors in subclasses
constructors.

-- 
           Summary: pure virtual destructor not overloaded, but accepted
           Product: gcc
           Version: 3.2.2
            Status: UNCONFIRMED
          Severity: critical
          Priority: P2
         Component: c++
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: b dot perschbacher at att dot net
                CC: gcc-bugs at gcc dot gnu dot org


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


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [Bug c++/15505] pure virtual destructor not overloaded, but accepted
  2004-05-18 15:32 [Bug c++/15505] New: pure virtual destructor not overloaded, but accepted b dot perschbacher at att dot net
@ 2004-05-18 15:33 ` b dot perschbacher at att dot net
  2004-05-18 15:39 ` pinskia at gcc dot gnu dot org
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: b dot perschbacher at att dot net @ 2004-05-18 15:33 UTC (permalink / raw)
  To: gcc-bugs


------- Additional Comments From b dot perschbacher at att dot net  2004-05-17 22:25 -------
Forgot to mention the compile command is:
g++ bug.C

and here is the output from the compiler:
/tmp/cc56si4w.o(.gnu.linkonce.t._ZN3subD1Ev+0x16): In function `sub::~sub
[in-charge]()':
: undefined reference to `base::~base [not-in-charge]()'
/tmp/cc56si4w.o(.gnu.linkonce.t._ZN3subC1Ev+0x64): In function
`sub::sub[in-charge]()':
: undefined reference to `base::~base [not-in-charge]()'
/tmp/cc56si4w.o(.gnu.linkonce.t._ZN4sub2D1Ev+0x16): In function `sub2::~sub2
[in-charge]()':
: undefined reference to `base::~base [not-in-charge]()'
/tmp/cc56si4w.o(.gnu.linkonce.t._ZN4sub2C1Ev+0x72): In function
`sub2::sub2[in-charge]()':
: undefined reference to `base::~base [not-in-charge]()'
/tmp/cc56si4w.o(.gnu.linkonce.t._ZN3subD0Ev+0x16): In function `sub::~sub
[in-charge deleting]()':
: undefined reference to `base::~base [not-in-charge]()'
/tmp/cc56si4w.o(.gnu.linkonce.t._ZN4sub2D0Ev+0x16): more undefined references to
`base::~base [not-in-charge]()' follow
collect2: ld returned 1 exit status


-- 


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


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [Bug c++/15505] pure virtual destructor not overloaded, but accepted
  2004-05-18 15:32 [Bug c++/15505] New: pure virtual destructor not overloaded, but accepted b dot perschbacher at att dot net
  2004-05-18 15:33 ` [Bug c++/15505] " b dot perschbacher at att dot net
@ 2004-05-18 15:39 ` pinskia at gcc dot gnu dot org
  2004-05-18 15:42 ` bangerth at dealii dot org
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: pinskia at gcc dot gnu dot org @ 2004-05-18 15:39 UTC (permalink / raw)
  To: gcc-bugs


------- Additional Comments From pinskia at gcc dot gnu dot org  2004-05-17 22:38 -------
I think this is required by the C++ standard to do it this way but I could be wrong, ICC 6.0 does the 
same thing in that it accepts the code and then the link fails.

-- 
           What    |Removed                     |Added
----------------------------------------------------------------------------
           Severity|critical                    |normal
           Keywords|                            |diagnostic


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


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [Bug c++/15505] pure virtual destructor not overloaded, but accepted
  2004-05-18 15:32 [Bug c++/15505] New: pure virtual destructor not overloaded, but accepted b dot perschbacher at att dot net
  2004-05-18 15:33 ` [Bug c++/15505] " b dot perschbacher at att dot net
  2004-05-18 15:39 ` pinskia at gcc dot gnu dot org
@ 2004-05-18 15:42 ` bangerth at dealii dot org
  2004-05-21  3:54 ` b dot perschbacher at att dot net
  2004-05-21 12:38 ` giovannibajo at libero dot it
  4 siblings, 0 replies; 6+ messages in thread
From: bangerth at dealii dot org @ 2004-05-18 15:42 UTC (permalink / raw)
  To: gcc-bugs


------- Additional Comments From bangerth at dealii dot org  2004-05-17 23:07 -------
Since you don't explicitly declare the existence of a user-defined 
destructor in the derived class, the compiler synthesizes it automatically 
for you. Thus, the derived class does have a final implementation of the 
pure virtual function. This explains why the compiler (correctly) accepts 
your code. 
 
The standard allows to declare pure destructors, but since base classes  
have to be destroyed anyway, you have to define it in addition. The lack 
of a definition explains why the linker (correctly) complains about a 
function definition. 
 
Thus, your code is invalid and gcc is right, sorry. 
 
Wolfgang 

-- 
           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |RESOLVED
         Resolution|                            |INVALID


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


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [Bug c++/15505] pure virtual destructor not overloaded, but accepted
  2004-05-18 15:32 [Bug c++/15505] New: pure virtual destructor not overloaded, but accepted b dot perschbacher at att dot net
                   ` (2 preceding siblings ...)
  2004-05-18 15:42 ` bangerth at dealii dot org
@ 2004-05-21  3:54 ` b dot perschbacher at att dot net
  2004-05-21 12:38 ` giovannibajo at libero dot it
  4 siblings, 0 replies; 6+ messages in thread
From: b dot perschbacher at att dot net @ 2004-05-21  3:54 UTC (permalink / raw)
  To: gcc-bugs


------- Additional Comments From b dot perschbacher at att dot net  2004-05-20 02:34 -------
Subject: Re:  pure virtual destructor not overloaded, but accepted

Sorry I haven't gotten back sooner, but I've been busy tracking down a
different bug.

Anyway I tried your suggestion of also declaring a destructor for the base
class and the compiler throws that back in my face with an overloading
error. So that clearly isn't allowed. Personally I think that virtual
destructors are are best dangerous and at worst useless, I just ran across
it in code I am maintaining.

As for the correctness of a generated function satisfing pure virtual
requirements, that totally circumvents the concept of pure virtual. This
point though goes to my previous statement on the usefulness of such a thing
so I'd just as soon leave this as "whatever."

If the standard explictly states that pure virtual destructors have to be
supported then yes this bug is invalid, but then so is the standard since it
forces the acceptance of invalid(as you put it) code. If the standard does
not explictly declare this then this bug is not invalid, but maybe
mislabeled.

Not forcing the overloading of that destructor, or even allowing a class to
quirkily avoid destruction is so dangerous that I can't express it in words,
but this is what happens with this (the code I am maintaining with this
error compiled and ran on several systems including one with an older gnu
compiler) being an accepted syntax. Just blowing this off is not the right
thing to do here, but "fixing" the compiler may not be an option just yet
either.


Brent
----- Original Message ----- 
From: "bangerth at dealii dot org" <gcc-bugzilla@gcc.gnu.org>
To: <b.perschbacher@att.net>
Sent: Monday, May 17, 2004 5:07 PM
Subject: [Bug c++/15505] pure virtual destructor not overloaded, but
accepted


>
> ------- Additional Comments From bangerth at dealii dot org  2004-05-17
23:07 -------
> Since you don't explicitly declare the existence of a user-defined
> destructor in the derived class, the compiler synthesizes it automatically
> for you. Thus, the derived class does have a final implementation of the
> pure virtual function. This explains why the compiler (correctly) accepts
> your code.
>
> The standard allows to declare pure destructors, but since base classes
> have to be destroyed anyway, you have to define it in addition. The lack
> of a definition explains why the linker (correctly) complains about a
> function definition.
>
> Thus, your code is invalid and gcc is right, sorry.
>
> Wolfgang
>
> -- 
>            What    |Removed                     |Added
> --------------------------------------------------------------------------
--
>              Status|UNCONFIRMED                 |RESOLVED
>          Resolution|                            |INVALID
>
>
> http://gcc.gnu.org/bugzilla/show_bug.cgi?id=15505
>
> ------- You are receiving this mail because: -------
> You reported the bug, or are watching the reporter.



-- 


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


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [Bug c++/15505] pure virtual destructor not overloaded, but accepted
  2004-05-18 15:32 [Bug c++/15505] New: pure virtual destructor not overloaded, but accepted b dot perschbacher at att dot net
                   ` (3 preceding siblings ...)
  2004-05-21  3:54 ` b dot perschbacher at att dot net
@ 2004-05-21 12:38 ` giovannibajo at libero dot it
  4 siblings, 0 replies; 6+ messages in thread
From: giovannibajo at libero dot it @ 2004-05-21 12:38 UTC (permalink / raw)
  To: gcc-bugs


------- Additional Comments From giovannibajo at libero dot it  2004-05-20 11:36 -------
(In reply to comment #4)

> Anyway I tried your suggestion of also declaring a destructor for the base
> class and the compiler throws that back in my face with an overloading
> error. So that clearly isn't allowed. 

This compiles correctly with GCC 3.4.0:

----------------------------------------------
extern "C" int printf(const char*, ...);

struct A {
  virtual ~A() = 0;
};

A::~A()
{ printf("A::~A\n"); }

struct B : A {
  ~B() { printf("B::~B\n"); }
};

int main()
{
  B b;
}
----------------------------------------------

and its output is:

------
B::~B
A::~A
------

as expected. If you comment the line with B's destructor definition, it still 
compiles correctly: in fact, B's destructor is synthetized automatically by the 
compiler (as it always happens with all classes), so the type is not abstract 
anymore. 

I am not sure what you tried to do, but it was a wrong try.

> Personally I think that virtual
> destructors are are best dangerous and at worst useless, I just ran across
> it in code I am maintaining.

you are speaking of *pure* virtual destructors here I hope, as virtual 
destructors are very common and very useful.

> As for the correctness of a generated function satisfing pure virtual
> requirements, that totally circumvents the concept of pure virtual. This
> point though goes to my previous statement on the usefulness of such a thing
> so I'd just as soon leave this as "whatever."

It probably circumvents *your* concept of pure virtual. Let me bet something 
that you will be surprised that the following code is actually valid C++, and 
can be compiled, linked and executed correctly by conforming compilers 
(including GCC 3.4.0):


---------------------------------------------
extern "C" int printf(const char*, ...);

struct A {
  virtual void foo(void) = 0;
};

void A::foo(void)
{ printf("A::foo\n"); }

struct B : A {
  virtual void foo(void)
  { printf("B::foo\n"); }
};

int main()
{
  B b;
  b.foo();
  b.A::foo();
}
---------------------------------------------

Its output is what you'd expect, that is:

-------
B::foo
A::foo
-------

A pure virtual function is just a normal virtual function, which just has the 
property of making the class in which it is defined abstract. In my example, A 
is still an abstract type by all means: if you try to declare a variable of 
type A you will get an error. The fact that the pure virtual function has a 
definition does not change a thing. 

The definition of a pure virtual function is required if and only if the 
virtual function is called through the qualified-id syntax (C++ standard, 
[class.abstract]/2). Destructors can be defined pure virtuals, but, as you 
know, they are always called even if you declare an object of a derived type: 
in this case, you always need to provide a definition of the destructor (if you 
define at least an object of that type or any derived type) (C++ standard, 
[class.dtor]/7).

> Not forcing the overloading of that destructor, or even allowing a class to

(BTW: the term "overloading" is inappropriate here. There is no overloading 
going on. I guess you wanted "override")

> quirkily avoid destruction is so dangerous that I can't express it in words,
> but this is what happens with this (the code I am maintaining with this
> error compiled and ran on several systems including one with an older gnu
> compiler) being an accepted syntax. 

No, you are confused. Defining a destructors as pure virtual does not mean that 
there will be no destructors executed for that class. You still have to provide 
a definition for the destructor, in fact.

Hope this clarifies the issue. If you are still not convinced, I suggest you to 
consult a good C++ book about this.

-- 
           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |giovannibajo at libero dot
                   |                            |it


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


^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2004-05-20 11:36 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-05-18 15:32 [Bug c++/15505] New: pure virtual destructor not overloaded, but accepted b dot perschbacher at att dot net
2004-05-18 15:33 ` [Bug c++/15505] " b dot perschbacher at att dot net
2004-05-18 15:39 ` pinskia at gcc dot gnu dot org
2004-05-18 15:42 ` bangerth at dealii dot org
2004-05-21  3:54 ` b dot perschbacher at att dot net
2004-05-21 12:38 ` giovannibajo at libero dot it

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).