To Arvind,
This is what i've send you.
"An object at construction does not call its destructor, in case of exception or error.
A destructor exists only if the instantiated object had successfully been constructed."

And the following is its detailed explanation. 

An object is only considered to have started its lifetime when the
(non-delegating) constructor for that object returns. In a
constructor, base classes are initialized first (declaration order),
then members (also declaration order), and finally the body of the
constructor. Only when an object is constructed successfully can it be
destroyed.

If a member's initialization fails via an exception, then the object
that it was a member of was *never constructed*. Its destructor does
not get called because its constructor never concluded, let alone
began. This means that the outer object never really existed.

A destructor only gets called on objects that were successfully
constructed. In the case of a member's initialization throwing an
exception, any members & base classes that were successfully
constructed up to that point are destroyed, in reverse declaration
order.

So let's thank Jason for his time to write all this.

Now to Jason,

Your ultimate point, that each constructor currently already needs to
keep track of which objects have been constructed, is wrong. Because
each constructor initializes subobjects in the same order, any
particular constructor only has to keep track of how many subobjects
have been initialized before the exception. When the exception
happens, it can simply jump to the destruction code for destroying all
prior objects. Because they all share the same construction ordering,
they all share the same destruction ordering too.

That was not my ultimate point,
I used the idea of "keep track", to explain to others that in certain way we already know from where to start destroying our object under construction. 

What you want would require each constructor to have its own set of
destruction orderings to match their separate construction ordering.

No! I'm not saying that.

Plus, you turn a very simple rule (subobjects are initialized in
declaration order) into a complex one (subobjects are initialized
maybe in declaration order and maybe not, depending on the
constructor).

Yes it is a simple idea, and its implementation is lazy.
First of all, let me explain what i mean by keep track.
1- we should understand that member initialization list i.e subobject members construction, is just a list of calls to constructors.
2- constructors are simply functions,  most of them are inlined, few of them are actual function calls.
3- calling these functions (i.e member constructors) in the context of constructing the object, is creating a stack frame.
4- raising an exception during this process, is just a matter of unwinding that stack frame. call it back tracking.

So physically we are using the "Stack Segment" to keep track of what was successfully constructed in the list of subobject members, right! LIFO
There is no custom destructors involved, no extra mechanism to handle destructions, nothing. It is already implemented by default.

If you want C++ to be an intuitive language, one key to
that is to have simple rules.

Yes very much, i want.

The current implementation which assumes that the member initialization list calls the member subobjects constructors in order of declaration, otherwise garbage is produced.
This is disaster!

Where is the difficulty to implement it the following way:
1- At compile time, scan the constructor member initialization list.
2- create a dependency graph.
3- make sure that class subobjects are initialized first in their order of inheritance. 
4- generate code for the constructor under compilation, which will call the member subobjects constructors in different order than their declaration order in the class, as per the user wish.

Isn't more intuitive?
As a program writer, i will be free to not watch in which order i initialize my member objects, when writing my constructor. 

It is so flexible and saves the day.

An object constructor is sensible piece of code, making it non-intuitive could lead to disaster. 

Just imagine this scenario:
" some developer want to write the constructor of a defibrillator,  then by mistake he didn't respect the order of initialization of just one member object, now his defibrillator instead of starting at ZERO volts power, it starts at a random value. 
Two consequences,  either his code damages the machine, or kills the patient"

That's why, I'm taking the pain the keep answering. 
Otherwise,  I don't care!

Nadir
Sent from my Galaxy


-------- Original message --------
From: Jason McKesson via Std-Proposals <std-proposals@lists.isocpp.org>
Date: 2/26/22 9:39 AM (GMT+04:00)
To: std-proposals@lists.isocpp.org
Cc: Jason McKesson <jmckesson@gmail.com>
Subject: Re: [std-proposals] Relax condition for potentially invoked destructor in constructor

On Fri, Feb 25, 2022 at 7:28 PM organicoman via Std-Proposals
<std-proposals@lists.isocpp.org> wrote:
>
> Here's an abbreviated version illustrating the behavior: https://godbolt.org/z/63G5v63h3
>
> The output is:
> ctor
> dtor
> Exception: boom
>
> The ctor/dtor are for "f1", and there is no ctor/dtor for the other "f2".
> Which means the destructor does know from where to start destroying,  right?

No.

An object is only considered to have started its lifetime when the
(non-delegating) constructor for that object returns. In a
constructor, base classes are initialized first (declaration order),
then members (also declaration order), and finally the body of the
constructor. Only when an object is constructed successfully can it be
destroyed.

If a member's initialization fails via an exception, then the object
that it was a member of was *never constructed*. Its destructor does
not get called because its constructor never concluded, let alone
began. This means that the outer object never really existed.

A destructor only gets called on objects that were successfully
constructed. In the case of a member's initialization throwing an
exception, any members & base classes that were successfully
constructed up to that point are destroyed, in reverse declaration
order.

Your ultimate point, that each constructor currently already needs to
keep track of which objects have been constructed, is wrong. Because
each constructor initializes subobjects in the same order, any
particular constructor only has to keep track of how many subobjects
have been initialized before the exception. When the exception
happens, it can simply jump to the destruction code for destroying all
prior objects. Because they all share the same construction ordering,
they all share the same destruction ordering too.

What you want would require each constructor to have its own set of
destruction orderings to match their separate construction ordering.

Plus, you turn a very simple rule (subobjects are initialized in
declaration order) into a complex one (subobjects are initialized
maybe in declaration order and maybe not, depending on the
constructor). If you want C++ to be an intuitive language, one key to
that is to have simple rules.
--
Std-Proposals mailing list
Std-Proposals@lists.isocpp.org
https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals