Re: Virtual Destructor - Implication & Specification
jaibuduvin@gmail.com (Le Chaud Lapin) wrote (abridged):
2. Class-specific new/delete
In my haste, I made an error. #2 Does _not_ solve the new/delete
mismatch problem.
Why not?
I've read the thread, and despite all the verbiage I don't see a clear
explanation of why this doesn't work if the class-specific new/delete are
not inline. Most of the thread is about explaining why virtual destructors
do work, which I already understand (and I consider to be implementation
specific).
If we have code like:
// One.hpp
struct One {
void *operator new( size_t );
void operator delete( void *, size_t );
One *make();
};
//////////////////////////////////
// Two.cpp
#include "One.hpp"
int main() {
One *p = One::make();
delete p; // Which delete does this invoke?
}
//////////////////////////////////
// One.cpp
#include "One.hpp"
#include <cstdlib>
void *One::operator new( size_t sz ) {
return malloc( sz );
}
void One::operator delete( void *p, size_t ) {
//std::cout << "Here\n";
free( p );
}
One *One::make() {
return new One;
}
It seems to me that the language guarantees that the delete expression in
Two.cpp will invoke the class-specific delete operator in One.cpp. Are you
saying that does not happen with VC++? If so, are you also saying that
this is standard-conformant, or is it an implementation-specific quirk of
how Microsoft implements DLLs?
Or are you saying that execution does reach the class-specific operator
delete, but that it somehow calls the wrong version of free()? If so, that
again would be hugely surprising to me. The calls to free() and malloc()
are in the same compilation unit so how can the compiler get it wrong?
If we had declared the class-specific new and delete inline, then they
would end up in different compilation units and effectively find different
versions of malloc() and free() in scope. We'd have a kind of violation of
the One Definition Rule. Then I would not be surprised if it went wrong.
We need the definitions to be out of line.
(Add to the code whatever extra declarations Microsoft needs to export and
import the functions. I don't have access to VC++ at the moment to test
this. Also, I wanted to show the code in pure form to be clear about the
expected behaviour if DLLs are not involved.)
This is actually what my colleagues keey saying, which I keep refuting.
I sympathise with them. Are you sure your refutations didn't define the
class-specific new and delete inline?
This just goes to show that, if you hear incorrect information often
enough, you start repeating it.
It's not a matter of repeating what I've heard, it's a matter of what
makes sense given the C++ language definition. At this point I would like
to know whether I've misunderstood the standard (in which case please give
details), or whether this is just some idiosyncrasy of VC++ (I won't call
it a bug because it involves DLLs, but I want to), or what.
Finally, elsewhere you have talked about a Virtually_Destructible template
which works around this problem. Everyone who reads this thread ought also
be aware of boost::shared_ptr, which also provides a solution.
-- Dave Harris, Nottingham, UK.
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]