Johan
Ville, I see your point, but so far I still think defined behaviour would be preferred.
The only case when you will have a bug and defined behaviour at the same time, is when the desctructor is non-empty. Of course, this kind of bugs are hard to track down. But if the destructor is supposed to do some work, and for the reason of delete via pointer-to-base is not executed, the program will not run as you expected it to. There can still be symptoms. Most importantly, the program remains in a valid state. Your system tests will still work in production.
The undefined behaviour on the other hand is unpredictable, so anything can happen. A program that can't be trusted may be useless or dangerous at worst. If you're lucky, that missile you mention will visibly go off in debug mode before you go into production. Let's pray the missile dives into the ocean. If you're not lucky, some seemingly random minor change will happen that keeps your program running without any diagnostics being reported, and you will never know why your program state changed.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposal...@isocpp.org.
To post to this group, send email to std-pr...@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
It's common to derive from a class and only add things like convenience constructors. That means the memory footprint (and object size) of the base class and the derived class is exactly the same and there's no risk of dangerous slicing.
When there are no derived members to destroy, this may "only" lead to unexpected results (resources not being released, or whatever the omitted destructor was supposed to do unless it's empty) in case of accidential deletion through a pointer-to-base.
But at least the behaviour would be defined and reproducable with different compilers! I think that is a slightly better (less evil) alternative to undefined behaviour, if there's any chance of possible standardization.Of course, this still does not mean that anyone should intentionally write code that deletes via base-to-pointer!
On 27 February 2014 15:25, David Krauss <pot...@gmail.com> wrote:
On Feb 27, 2014, at 7:19 PM, Ville Voutilainen <ville.vo...@gmail.com> wrote:Well, I guess it's certainly possible, for cases where the derived
class destructor
is trivial.
The lifetime of trivially-destructible types ends arbitrarily; it doesn't matter whether the destructor runs or not. I don't think the current language specifies UB if you happen to arbitrarily call the trivial destructor of a base subobject before neglecting to call the trivial destructor of the derived class.
Perhaps you're even allowed to call the same trivial destructor twice. I don't see why not; they don't do anything at all. (ATM I had a couple drinks and it's bedtime though.)
The current wording doesn't care whether the destructors are trivial.
The case we hit
is [expr.delete]/3, which says
"if the static type of the object to be deleted is different from its
dynamic type, the static type shall be a base class of the dynamic
type of the object to be deleted and the
static type shall have a virtual destructor or the behavior is undefined. “
That doesn't supersede paragraph 3, as far as I can see. So, as long
as the static and
dynamic type differ, deleting is undefined behavior if the destructor
is not virtual. Therefore,
it doesn't help that either the base or derived destructor is trivial.
That's what this thread
is originally proposing to change.