BUG: compiler allows for creation of objects without destructor compiled

  • Thread starter Maxim Yegorushkin
  • Start date
M

Maxim Yegorushkin

The following code:

#include <iostream>

class base
{
private:
virtual ~base()
{
std::cout << "virtual ~base()\n";
}
};

class derived : public base // must result in a compile time error
{
// does result in a compile time error when uncommented
//~derived() {}
};

int main()
{
// does result in a compile time error when uncommented
//derived dd;

derived* d = new derived;
delete d;
}

Produces no error when compiled thought it must. It only produces 2
warnings:

warning C4624: 'derived' : destructor could not be generated because a
base class destructor is inaccessible
warning C4527: instances of class 'derived' can never be destroyed -
user-defined destructor required

The second warning is false - the code does create an instance of derived
and what much worse it does destroy it. At runtime it seems like base's
destructor does not get called.
 
G

Guest

Hi ,
Try this :
class bas

public
virtual ~base(

TRACE("virtual ~base()\n")

}

class derived : public base // must result in a compile time erro

// does result in a compile time error when uncommente
public :
~derived() {}
}

See the code you have written. : you have made destructor "Private ". So that it would not be visible in derived also.
That's why it is giving compile time error.
 
H

Hendrik Schober

Rudresh said:
[...]
See the code you have written. : you have made destructor "Private ".
So that it would not be visible in derived also.
That's why it is giving compile time error.


Look at the posting again. I'd say:
"That's why it _should_ be giving a
compile-time error."
I'd call this a bug. So does Comeau:

Comeau C/C++ 4.3.3 (Aug 6 2003 15:13:37) for ONLINE_EVALUATION_BETA1
Copyright 1988-2003 Comeau Computing. All rights reserved.
MODE:strict errors C++

"ComeauTest.c", line 12: error: "base::~base()" is inaccessible
class derived : public base // must result in a compile time error
^
detected during implicit generation of "derived::derived()" at line
23

"ComeauTest.c", line 12: error: "base::~base()" is inaccessible
class derived : public base // must result in a compile time error
^
detected during:
implicit generation of "derived::~derived()" at line 23
implicit generation of "derived::derived()" at line 23

2 errors detected in the compilation of "ComeauTest.c".

Schobi

--
(e-mail address removed) is never read
I'm Schobi at suespammers dot org

"Sometimes compilers are so much more reasonable than people."
Scott Meyers
 
M

Maxim Yegorushkin

Rudresh said:
See the code you have written. : you have made destructor "Private ". So

That is my intent.
that it would not be visible in derived also.
That's why it is giving compile time error.

The problem is that it *does not* give a compile error but it must.
 
D

David Olsen

Maxim said:
The following code: [edited for brevity]

#include <iostream>
class base
{
private:
virtual ~base() { }
};
class derived : public base { };

int main()
{
derived* d = new derived;
delete d;
}

Produces no error when compiled thought it must. It only produces 2
warnings:

According to the C++ standard (12.4/5) it is not an error to define a
class whose destructor cannot be defined (class "derived" in your
example). But it is an error to actually call the destructor of that
class. So the code
delete d;
should be an error, since it calls class derived's destructor. It is a
bug in the compiler that the error is not being reported. The bug is
still present in VC7.1.
 
M

Maxim Yegorushkin

David Olsen wrote:

[]
According to the C++ standard (12.4/5) it is not an error to define a
class whose destructor cannot be defined (class "derived" in your
example). But it is an error to actually call the destructor of that
class.

Does it mean that Comeau is wrong about producing the error message in
Hendrik Schober's posting?
 
D

David Olsen

Maxim said:
Does it mean that Comeau is wrong about producing the error message in
Hendrik Schober's posting?

Yes and no. Comeau online (http://www.comeaucomputing.com/tryitout/)
seems to have it bugs in this area, which are different than VC's bugs.
It correctly accepts:

class base { virtual ~base() { } };
class derived : public base { };

But it rejects the following, which should be valid code because the
destructor is never used:

class base { virtual ~base() { } };
class derived : public base { };
derived *f() { return new derived; }

And it accepts the following, which it should reject because the
destructor is used:

class base { virtual ~base() { } };
class derived : public base { };
void f(derived *x) { delete x; }
 
C

Carl Daniel [VC++ MVP]

Maxim said:
So, are MS compiler guys going to fix it?

It's already fixed in Whidbey ("VC8").
cl -c -EHs privatedest0408.cpp
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 14.00.40309 for 80x86
Copyright (C) Microsoft Corporation. All rights reserved.

privatedest0408.cpp
privatedest0408.cpp(8) : warning C4624: 'derived' : destructor could not be
generated because a base class destructor is inaccessible
privatedest0408.cpp(14) : error C2248: 'base::~base' : cannot access private
member declared in class 'base'
privatedest0408.cpp(5) : see declaration of 'base::~base'
privatedest0408.cpp(3) : see declaration of 'base'
This diagnostic occurred in the compiler generated function
'derived::~derived(void)'

Since there's an easy workaround (just don't write illegal code) it's
unlikely that this will be fixed in any other form (patch, service pack,
etc) before Whidbey ships ("1st half of 2005" is the latest official word).

-cd
 
M

Maxim Yegorushkin

David said:
Yes and no. Comeau online (http://www.comeaucomputing.com/tryitout/)
seems to have it bugs in this area, which are different than VC's bugs.
[]

But it rejects the following, which should be valid code because the
destructor is never used:

class base { virtual ~base() { } };
class derived : public base { };
derived *f() { return new derived; }

I believe Comeau rejects it correctly. If derived constructor throws here
the base subobject destructor must be called (and then operator delete to
deallocate storage). But the base destructor is unaccessable.
 
M

Maxim Yegorushkin

Carl Daniel [VC++ MVP] <[email protected]>
wrote:

[]
Since there's an easy workaround (just don't write illegal code) it's
unlikely that this will be fixed in any other form (patch, service pack,
etc) before Whidbey ships ("1st half of 2005" is the latest official
word).

I think the advice not to write illegal code has proved to be completely
useless and did not save MS consumers from writing tons of illegal code
with errors like binding non-const references to temporaries.
 
C

Carl Daniel [VC++ MVP]

Maxim said:
Carl Daniel [VC++ MVP]
Since there's an easy workaround (just don't write illegal code) it's
unlikely that this will be fixed in any other form (patch, service
pack, etc) before Whidbey ships ("1st half of 2005" is the latest
official word).

I think the advice not to write illegal code has proved to be
completely useless and did not save MS consumers from writing tons of
illegal code with errors like binding non-const references to
temporaries.

There's an important difference though: In the case you cite people were
(are, will be) writing illegal (according to the standard) that does
something useful, well defined and predictable with a particular
(pre-standard) tool.

In the case of this bug the resulting program clearly doesn't execute as
intended so it's very unlikely that there's a substantial body of code
that's relying on this non-standard (undocumented, undefined, unpredictable)
behavior.

-cd
 
E

Edward Diener

Carl said:
It's already fixed in Whidbey ("VC8").

Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 14.00.40309
for 80x86 Copyright (C) Microsoft Corporation. All rights reserved.

privatedest0408.cpp
privatedest0408.cpp(8) : warning C4624: 'derived' : destructor could
not be generated because a base class destructor is inaccessible
privatedest0408.cpp(14) : error C2248: 'base::~base' : cannot access
private member declared in class 'base'
privatedest0408.cpp(5) : see declaration of 'base::~base'
privatedest0408.cpp(3) : see declaration of 'base'
This diagnostic occurred in the compiler generated function
'derived::~derived(void)'

Since there's an easy workaround (just don't write illegal code) it's
unlikely that this will be fixed in any other form (patch, service
pack, etc) before Whidbey ships ("1st half of 2005" is the latest
official word).

You say that as if you believe that if a serious some bug has no easy
workaround it is likely that it will be fixed before Whidbey ships <g> .
 
M

Maxim Yegorushkin

Maxim said:
Carl Daniel [VC++ MVP]
Since there's an easy workaround (just don't write illegal code) it's
unlikely that this will be fixed in any other form (patch, service
pack, etc) before Whidbey ships ("1st half of 2005" is the latest
official word).

I think the advice not to write illegal code has proved to be
completely useless and did not save MS consumers from writing tons of
illegal code with errors like binding non-const references to
temporaries.

There's an important difference though: In the case you cite people were
(are, will be) writing illegal (according to the standard) that does
something useful, well defined and predictable with a particular
(pre-standard) tool.

In the case of this bug the resulting program clearly doesn't execute as
intended so it's very unlikely that there's a substantial body of code
that's relying on this non-standard (undocumented, undefined,
unpredictable)
behavior.

Yes, that makes a difference.
 
C

Carl Daniel [VC++ MVP]

Edward said:
You say that as if you believe that if a serious some bug has no easy
workaround it is likely that it will be fixed before Whidbey ships
<g> .

If a serious bug has no easy workaround and you make the appropriate
overtures with PSS, there IS a fair chance that it will be fixed before
Whidbey ships. Of course, "serious" has to be properly defined. If you
have a 10MLOC source code base that built with VC6 but doesn't run when
built with VC7.1 due to a codegen bug with no tractable workaround, that'd
be SERIOUS. If you reported such a bug to PSS, it's pretty likely that
you'd get a fix.

If you find a bug that prevents you from using some particular idiom that
compiles correctly with GCC but not VC7.1, I'd guess you'd be a lot less
likely to wrangle a patch out of PSS since the obivous solution is to simply
not use that idiom when writing new code.

-cd
 
E

Edward Diener

Carl said:
If a serious bug has no easy workaround and you make the appropriate
overtures with PSS, there IS a fair chance that it will be fixed
before Whidbey ships. Of course, "serious" has to be properly
defined. If you have a 10MLOC source code base that built with VC6
but doesn't run when built with VC7.1 due to a codegen bug with no
tractable workaround, that'd be SERIOUS. If you reported such a bug
to PSS, it's pretty likely that you'd get a fix.

I believe that the infamous DLL initialization bug for mixed mode C++
programming of assemblies in NET 2003 is a serious bug. The workaround of
creating a pure mode assembly is not a viable option for C++ programmers
whose use of the C++ standard library is by far the norm in C++ programming.
Microsoft's unwillingness to fix this for the life of .NET 2003 is an
example of a company using their monetary power to greatly inhibit the use
of a community of programmers, C++ programmers, when it comes to the .NET
programming world. There are no other workarounds except no to do mixed mode
DLL assembly programming in C++ for .NET 2003. There is no reasoning for not
having put out a service pack for .NET 2003 as quickly as possible, once
this bug was discovered which was shortly after the release of .NET 2003,
for fixing this problem. Telling C++ programmers that their mixed mode
assembly may hang up the end-user, no matter how slim a chance this may be,
and that there is no sure workaround to this except not to write mixed mode
DLL assemblies, is tantamount to telling C++ programmers that they can not
write mixed mode DLL assembles in C++ for .NET 2003, in other words that
they can not write reusable components and classes in .NET 2003 in their own
languiage in the normal way.

This is one of the primary examples in my career as a programmer of a bug
which a company should have fixed and has decided not to.
 
D

David Lowndes

Microsoft's unwillingness to fix this for the life of .NET 2003 is an
example of a company using their monetary power to greatly inhibit the use
of a community of programmers, C++ programmers, when it comes to the .NET
programming world.

Why wouldn't it be in MS's (financial) interests to have C++
developers completely happy to use .Net?

From comments I've seen regarding this problem, it was pretty deep
rooted and difficult to fix.

Dave
 
C

Carl Daniel [VC++ MVP]

Edward said:
I believe that the infamous DLL initialization bug for mixed mode C++
programming of assemblies in NET 2003 is a serious bug. The
workaround of creating a pure mode assembly is not a viable option
for C++ programmers whose use of the C++ standard library is by far
the norm in C++ programming. Microsoft's unwillingness to fix this
for the life of .NET 2003 is an example of a company using their
monetary power to greatly inhibit the use of a community of
programmers, C++ programmers, when it comes to the .NET programming
world.

You're 100% wrong about that. The reason the VC++ team didn't provide a
real fix to the loader lock issue until Whidbey is twofold (as I understand
it). First, the issue was not fully understood until very late in the
Everett (7.1) beta cycle. At that point it was too late to build a proper
fix but there was time to do something, which they did. Second, the problem
has it's roots deep inside the NT loader and the CLR and required changes
far outside the realm of the VC++ team to fix - it simply wasn't possible to
coordinate such a deep and far-reaching change until Whidbey. It's
unfortunate. No one likes it. No one's very happy about it. But to
attribute MS's response to this bug to muscle flexing or malice is simply
ignorant.

-cd
 
E

Edward Diener

David said:
Why wouldn't it be in MS's (financial) interests to have C++
developers completely happy to use .Net?

Do you believe it is not in MS's financial interests to promote the use of
C#, even over C++, as a programming language ? I think you must be naive if
you believe so. I am not saying that is necessarily the reason why the bug
exists, but I believe, no matter what others will say, it is part of the
reason why no efforts were made to fix it in .NET 1.1.
From comments I've seen regarding this problem, it was pretty deep
rooted and difficult to fix.

It may have been difficult to fix but that is no reason not to do so for a
period which will extend more than two years by the time VC 2005 is
scheduled to finally be released.
 
E

Edward Diener

Carl said:
You're 100% wrong about that. The reason the VC++ team didn't
provide a real fix to the loader lock issue until Whidbey is twofold
(as I understand it). First, the issue was not fully understood
until very late in the Everett (7.1) beta cycle. At that point it
was too late to build a proper fix but there was time to do
something, which they did.

What was it which they did ?
Second, the problem has it's roots deep
inside the NT loader and the CLR and required changes far outside the
realm of the VC++ team to fix - it simply wasn't possible to
coordinate such a deep and far-reaching change until Whidbey.

I am sorry but I don't buy this sort of generality. Do you seriously mean to
tell me that it would take more than two months, much less two years, from a
team of programmers, to fix a problem such as this, no matter how
deep-rooted the problem is ?
It's
unfortunate. No one likes it. No one's very happy about it. But to
attribute MS's response to this bug to muscle flexing or malice is
simply ignorant.

Then I will be "ignorant" in your terms. First the term "malice" was never
used by me. I take it as a given that companies look to their own interests,
which revolve largely around making profits, over much of everything else. I
don't call this malice, but there is an element of greed over fairness which
is evident in corporate life. Secondly, to think that MS hasn't engaged in
muscle flexing in numerous areas numerous times is just ludicrous, but of
course that doesn't prove that they have done so here. Nonetheless when a
bug such as this exists, which makes it impossible for the programmers of
the leading computer language in the world to reliably write reusable code
for the leading programming environment in the world, and when this
situation exists for the lifetime of a particular release of that
environment and one is told that it is too difficult a problem to be fixed
for that lifetime, and when that lifetime exists for a period of two years
or more, and when the company producing that environment has also produced
other programming languages which compete with the previously mentioned
language, and when those other programming languages have no inherent
problems within the lifetime of that particular release of that environment
in reliably producing reusable code, I think it is natural to feel that
their may be some muscle flexing involved. If there isn't and this problem
is truly too difficult to fix for .NET 1.1, then my suggestion is that MS
needs to hire better programmers, period !
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top