Date: Fri, 25 Feb 2022 12:41:45 +0400
Arthur, Jason, Chris and alYes i forgot the member a in foo. That was because i didn't copy paste but rewrote the example in my email.Aside from that.I asked the question because i tested the code in the first place and found that it printed garbage, which was surprising for me.My compiler always warned me about initializing member data out of order, which I fix promptly, so i never witnessed a UB.Plus I am relying on the following mental model:-Comma operator does not imply ordering, which is the case for function arguments and variables initialization, - member initialization is a kinda of comma operator initialization, thus the ordering is not respected. And since all compilers allow the above code to compile, risking the situation of calling a deleted constructor, All that made me assume, that there is a graph dependency behind the scene for the case of member initialization. Like the following. struct test
> {
> bar b;
> foo f;
> int a;
> test(): b(f), f(a), a(22) {}
> };
>So calling "test()" construtor, in my logic, will do the following:- i want to initialize "b", but what does "f" refer to?- ok let's find "f" and initialize it,- good found "f", but what "a" refers to?-look for "a",-ok "a" is an 'int', initialized to be equal to 22.- let's back track, - "f", inited - "b" , inited- "test" constructed Now in case any of the members throw an exception, then all the members data that were fully constructed are allowed to call their destructor. Exactly as per the standard "potentially constructed -> potentially call destructor"That was my mental model, and that was how i would implement it.Now given that situation above, that at time of construction i can call deleted constructors, or do things that are considered by the compiler as obvious errors. This is horrible!A lot of assumptions needs to be rethought. Very confusing Sent from my Galaxy
-------- Original message --------From: Chris Ryan via Std-Proposals <std-proposals_at_[hidden]> Date: 2/25/22 10:57 AM (GMT+04:00) To: std-proposals_at_[hidden] Cc: Chris Ryan <chrisr98008_at_[hidden]> Subject: Re: [std-proposals] Relax condition for potentially invoked destructor in constructor >"
The choice of allowing you to specify members in the memberinitialization list out of order from their order of initialization?Honestly, I have no idea why that was ever legal."Quickly looking I could not find the reference for it but I did not think that it was ever legal.Most every compiler I tested (on godbolt) did report it as a warning (-Wreorder) with -Wall or /Wall. "Initializer order does not match the declaration order" or something like that depending on your compilerIt doesn't make sense that it should be allowed since the destruction order must be the reverse order of construction.You can't have many constructors use many orders of initialization but only one destructor and it needs to use the reverse order (of declaration).You can not have multiple destructors where each one destructs in reverse order of construction depending on the constructor used.If the destructor must be in reverse order of declaration, construction must be in order of declaration as must be the member initialization list.On Thu, Feb 24, 2022 at 6:24 PM Jason McKesson via Std-Proposals <std-proposals_at_[hidden]> wrote:On Thu, Feb 24, 2022 at 6:40 PM organicoman via Std-Proposals
<std-proposals_at_[hidden]> wrote:
>
> Hmm,
> That means that tglhe following code will print nonsense.
>
> struct foo
> {
> foo()=delete;
> foo(int _a) : a(_a) { printf("foo%d\n",a);}
> };
>
> struct bar
> {
> bar()=delete;
> bar(foo f) { printf("bar%d\n",f.a);}
> };
>
> struct test
> {
> bar b;
> foo f;
> int a;
> test(): b(f), f(a), a(22) {}
> };
>
> int main()
> {
> test t;
> return 0;
> }
>
> So instead of receiving a compiler error of a default constructor deleted for both bar and foo, i will receive junk!!
That's what happens when you use an object before it gets initialized.
> I seldomly read the standard, but this situation was out of discussion for me, since i assumed that i will logically receive a compiler error, and constructing a dependency graph between the data members was not that difficult to figure out.
> Can anyone explain the logic behind this choice of the standard?
What choice exactly?
The choice of allowing you to specify members in the member
initialization list out of order from their order of initialization?
Honestly, I have no idea why that was ever legal. There's probably a
historical reason for it.
The choice of allowing you to access an object's name before its
initialization? That ship sailed in C.
> {
> bar b;
> foo f;
> int a;
> test(): b(f), f(a), a(22) {}
> };
>So calling "test()" construtor, in my logic, will do the following:- i want to initialize "b", but what does "f" refer to?- ok let's find "f" and initialize it,- good found "f", but what "a" refers to?-look for "a",-ok "a" is an 'int', initialized to be equal to 22.- let's back track, - "f", inited - "b" , inited- "test" constructed Now in case any of the members throw an exception, then all the members data that were fully constructed are allowed to call their destructor. Exactly as per the standard "potentially constructed -> potentially call destructor"That was my mental model, and that was how i would implement it.Now given that situation above, that at time of construction i can call deleted constructors, or do things that are considered by the compiler as obvious errors. This is horrible!A lot of assumptions needs to be rethought. Very confusing Sent from my Galaxy
-------- Original message --------From: Chris Ryan via Std-Proposals <std-proposals_at_[hidden]> Date: 2/25/22 10:57 AM (GMT+04:00) To: std-proposals_at_[hidden] Cc: Chris Ryan <chrisr98008_at_[hidden]> Subject: Re: [std-proposals] Relax condition for potentially invoked destructor in constructor >"
The choice of allowing you to specify members in the memberinitialization list out of order from their order of initialization?Honestly, I have no idea why that was ever legal."Quickly looking I could not find the reference for it but I did not think that it was ever legal.Most every compiler I tested (on godbolt) did report it as a warning (-Wreorder) with -Wall or /Wall. "Initializer order does not match the declaration order" or something like that depending on your compilerIt doesn't make sense that it should be allowed since the destruction order must be the reverse order of construction.You can't have many constructors use many orders of initialization but only one destructor and it needs to use the reverse order (of declaration).You can not have multiple destructors where each one destructs in reverse order of construction depending on the constructor used.If the destructor must be in reverse order of declaration, construction must be in order of declaration as must be the member initialization list.On Thu, Feb 24, 2022 at 6:24 PM Jason McKesson via Std-Proposals <std-proposals_at_[hidden]> wrote:On Thu, Feb 24, 2022 at 6:40 PM organicoman via Std-Proposals
<std-proposals_at_[hidden]> wrote:
>
> Hmm,
> That means that tglhe following code will print nonsense.
>
> struct foo
> {
> foo()=delete;
> foo(int _a) : a(_a) { printf("foo%d\n",a);}
> };
>
> struct bar
> {
> bar()=delete;
> bar(foo f) { printf("bar%d\n",f.a);}
> };
>
> struct test
> {
> bar b;
> foo f;
> int a;
> test(): b(f), f(a), a(22) {}
> };
>
> int main()
> {
> test t;
> return 0;
> }
>
> So instead of receiving a compiler error of a default constructor deleted for both bar and foo, i will receive junk!!
That's what happens when you use an object before it gets initialized.
> I seldomly read the standard, but this situation was out of discussion for me, since i assumed that i will logically receive a compiler error, and constructing a dependency graph between the data members was not that difficult to figure out.
> Can anyone explain the logic behind this choice of the standard?
What choice exactly?
The choice of allowing you to specify members in the member
initialization list out of order from their order of initialization?
Honestly, I have no idea why that was ever legal. There's probably a
historical reason for it.
The choice of allowing you to access an object's name before its
initialization? That ship sailed in C.
-- Std-Proposals mailing list Std-Proposals_at_[hidden] https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
Received on 2022-02-25 08:41:52