Topic: destructor being called for NULL pointers


Author: Rotem Yaari <rotem@MailAndNews.com>
Date: Wed, 21 Feb 2001 19:51:33 GMT
Raw View
Hi all. Given this code:

class A {
public:
  ~A()
  {
    //do something do destruct a...
  }
};

...
...

A * pA = 0;
...
//pA is not modified during this code and remains 0...
...
delete pA;


will the destructor be called?

logic has it that the destructor will not be called. However, I tried it on
MSVC++6 and Borland C++ Builder 5, and both versions called the destructor!

This is a very troubling behaviour. this means that if we are writing a
class
that we fear someone would delete a 0 valued pointer of, we must write

if (this == NULL) {
  return;
}

in the destructor, fearing we might segfault!

I would really thank you if you tell me if this is noted by the standard,
and
what is the behaviour stated in it as the standard behaviour.

thanks,

Rotem

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: Ron Natalie <ron@spamcop.net>
Date: Wed, 21 Feb 2001 21:16:15 GMT
Raw View

Rotem Yaari wrote:

>
> A * pA = 0;
> ...
> //pA is not modified during this code and remains 0...
> ...
> delete pA;
>
> will the destructor be called?
>
> logic has it that the destructor will not be called. However, I tried it on
> MSVC++6 and Borland C++ Builder 5, and both versions called the destructor!
>
As stated in the other group you posted this in, the destructor should
not get called, and it does not in VC++.  I would be interested in seeing
the test case you have that you think refutes this.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: Ross Smith <ross.s@ihug.co.nz>
Date: Wed, 21 Feb 2001 21:21:50 GMT
Raw View
Rotem Yaari wrote:
>
> Hi all. Given this code:
>
> class A {
> public:
>   ~A()
>   {
>     //do something do destruct a...
>   }
> };
>
> ...
> ...
>
> A * pA = 0;
> ...
> //pA is not modified during this code and remains 0...
> ...
> delete pA;
>
> will the destructor be called?

No. "delete 0" is a harmless no-op. See section 5.3.5 para 2 of the C++
standard.

> logic has it that the destructor will not be called. However, I tried it on
> MSVC++6 and Borland C++ Builder 5, and both versions called the destructor!

You don't say? Borland I can't help you with, but I just tried it on VC6
and got the expected behaviour. Not that I seriously expected anything
else, since I've been relying on this behaviour in my code for years.

I strongly suspect that the code you've hidden in ellipses does
something  whose significance you haven't realised. Try coming up with a
complete program that you think demonstrates the problem.

--
Ross Smith <ross.s@ihug.co.nz> The Internet Group, Auckland, New Zealand
========================================================================
          "Normally he was insane, but he had lucid moments
          when he was merely stupid."     -- Heinrich Heine

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: Tom <the_wid@my-deja.com>
Date: Wed, 21 Feb 2001 15:24:30 CST
Raw View
Previously, Rotem Yaari wrote in comp.std.c++:
> Hi all. Given this code:
>
> class A {
> public:
>   ~A()
>   {
>     //do something do destruct a...
>   }
> };
>
> ...
> ...
>
> A * pA = 0;
> ...
> //pA is not modified during this code and remains 0...
> ...
> delete pA;
>
>
> will the destructor be called?

No. delete (A*)0; is a no-op.

>
> logic has it that the destructor will not be called. However, I tried it on
> MSVC++6 and Borland C++ Builder 5, and both versions called the destructor!

I find that very hard to believe. What was the exact compilable program that
demonstrated that they were calling the destructor when deleting a NULL
pointer?

>
> This is a very troubling behaviour. this means that if we are writing a
> class
> that we fear someone would delete a 0 valued pointer of, we must write
>
> if (this == NULL) {
>   return;
> }
>
> in the destructor, fearing we might segfault!

Such code is pointless, since if this == NULL you have already invoked
undefined behaviour.

>
> I would really thank you if you tell me if this is noted by the standard,
> and
> what is the behaviour stated in it as the standard behaviour.

The standard says that the destructor will not be called, and I have never
heard of a compiler that didn't follow the standard as far as this is
concerned. I suspect your test was flawed in some way.

Tom

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: "Homer Meyer" <homer@cqg.com>
Date: Wed, 21 Feb 2001 21:34:54 GMT
Raw View
"Rotem Yaari" <rotem@MailAndNews.com> wrote in message
news:3A9D565F@MailAndNews.com...
> Hi all. Given this code:
>
> class A {
> public:
>   ~A()
>   {
>     //do something do destruct a...
>   }
> };
>
> ...
> ...
>
> A * pA = 0;
> ...
> //pA is not modified during this code and remains 0...
> ...
> delete pA;
>
>
> will the destructor be called?
>
> logic has it that the destructor will not be called. However, I tried it
on
> MSVC++6 and Borland C++ Builder 5, and both versions called the
destructor!

That's funny.  I tried the following code on MSVC++ 6.0 SP3 and BC++ 5.5 and
neither one of them generated a call to the destructor.

#include <iostream>

class A {
public:
  ~A() { std::cout << "destructor called\n"; }
};

int main() {
  A* pa = 0;
  delete pa;
}

You didn't post complete code, so there is no way to tell whether or not you
did something that would cause an instance to be created and destroyed, but
as far as I can tell both MSVC++ and BC++ are correct in this regard.


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: Rotem Yaari <rotem@MailAndNews.com>
Date: Thu, 22 Feb 2001 13:08:33 GMT
Raw View
I am sorry, you are correct.

in MSVC++, I made a mistake and didn't look at the right thing.

as for Borland, the behaviour it's debugger offers is very strange. It
traces
the delete statement for a NULL pointer down to the destructor, but does not
call it... since I inlined the destructor there was no way for me at the
moment to see that nothing of the destructor body was being executed.

Strange behaviour for a debugger though.

Sorry again for the mis-information,

Rotem

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: Jon Biggar <jon@floorboard.com>
Date: Thu, 22 Feb 2001 19:34:44 GMT
Raw View
Rotem Yaari wrote:
>
> I am sorry, you are correct.
>
> in MSVC++, I made a mistake and didn't look at the right thing.
>
> as for Borland, the behaviour it's debugger offers is very strange. It
> traces
> the delete statement for a NULL pointer down to the destructor, but does not
> call it... since I inlined the destructor there was no way for me at the
> moment to see that nothing of the destructor body was being executed.
>
> Strange behaviour for a debugger though.

Some compilers implement the delete operation by calling the destructor
with a hidden flag that tells the destructor to free the memory (and
implement constructors in a similar fashion with a hidden flag telling
the constructor to allocate memory on the heap).

In this case, the compiler probably also generates hidden code at the
beginning of the destructor to test for a null pointer and return.  This
would explain why the debugger shows that the destructor is being called
without any of the user written code in the destructor actually
executing.

--
Jon Biggar
Floorboard Software
jon@floorboard.com
jon@biggar.org

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]