www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Temporary objects as function parameters or

reply Jack Applegame <japplegame gmail.com> writes:
If you don't want to get the great PITA, never create temporary 
objects in function parameters.
I recently spent a whole day digging through my reference counted 
containers library. But nasty bug was not there, but in the 
compiler.

Look at this: https://glot.io/snippets/eui2l8ov0r

Result:
 Bar.this(int): 7FFD3D60CD38
 fun: 7FFD3D60CD20
 Bar.~this(): 7FFD3D60CD20
Compiler creates struct on the stack and silently (without postblitting and destruction old object) moves it to another address. Is it normal? I don't think so. But that's not the most fun. Look at this: https://glot.io/snippets/eui2pjrwvi Result:
 Bar.this(int): 7FFF87DD2D31
 fun: 7FFF87DD2CE0
 Bar.~this(): 7FFF87DD2CE0
 Bar.~this(): 7FFF87DD2D31
WAT??? Compiler creates struct on the stack copies it without postblitting and destructs both objects. But if you create the structure before calling the function, then all will be well: https://glot.io/snippets/eui2vn2bu1 All this greatly angered me because there are several issues related wrong struct construction and destruction in the bugtracker. Because of these bugs my low level libraries full of strange hacks. I want to ask. How you guys are going to create a reliable RC library, if such fundamental bugs hang in the issue tracker for months and years. And instead of fixing them, you develop new minor bells and whistles. See: https://issues.dlang.org/buglist.cgi?quicksearch=destructor Since I myself can't fix such bugs (my knowledge in this area are extremely small), I have a question to Andrei Alexandrescu: Can I donate to the D Foundation and that my donations would be aimed at fixing exactly these bugs?
Oct 13 2017
next sibling parent ketmar <ketmar ketmar.no-ip.org> writes:
Jack Applegame wrote:

 Compiler creates struct on the stack and silently (without postblitting 
 and destruction old object) moves it to another address. Is it normal?
yes.
 WAT??? Compiler creates struct on the stack copies it without 
 postblitting and destructs both objects.
and this is the real bug.
Oct 13 2017
prev sibling next sibling parent reply Biotronic <simen.kjaras gmail.com> writes:
On Friday, 13 October 2017 at 10:35:56 UTC, Jack Applegame wrote:
 Compiler creates struct on the stack and silently (without 
 postblitting and destruction old object) moves it to another 
 address. Is it normal? I don't think so.
It is. Structs have no identity, and the compiler/GC/whatever is free to copy and/or move them about as it sees fit (as long as there is ostensibly only one - no duplicate constructor/destructor calls, no desynching of state). That's why the documentation[1] says not to have internal pointers in structs.
 WAT??? Compiler creates struct on the stack copies it without 
 postblitting and destructs both objects.
Now this looks like a real bug. There should be a this(this) call in there.
 Can I donate to the D Foundation and that my donations would be 
 aimed at fixing exactly these bugs?
BountySource[2] lets you do basically exactly that. [1]: https://dlang.org/spec/garbage.html, "Do not have pointers in a struct instance that point back to the same instance." [2]: https://www.bountysource.com/
Oct 13 2017
next sibling parent reply Jack Applegame <japplegame gmail.com> writes:
On Friday, 13 October 2017 at 11:21:48 UTC, Biotronic wrote:
 BountySource[2] lets you do basically exactly that.
My experience says that BountySource almost doesn't help.
Oct 13 2017
parent reply Michael V. Franklin <slavo5150 yahoo.com> writes:
On Friday, 13 October 2017 at 11:54:38 UTC, Jack Applegame wrote:
 On Friday, 13 October 2017 at 11:21:48 UTC, Biotronic wrote:
 BountySource[2] lets you do basically exactly that.
My experience says that BountySource almost doesn't help.
It works if the bounty is worth someone sacrificing their free time to do the work. For example, I'd attempt fixing the bug if the bounty were greater than $200, but I don't know if I'd be successful, as I've only just started working working with the DMD source code. It would be nice if the D Foundation would do some kind of creative incentivizing, such as prioritizing bugs, and matching bounty contributions. But even then, you might run the risk of the work being done, but having the PR sit in purgatory for an indeterminate length of time. I'm not at all happy with the way D is managed, but I'm also lacking any actionable solutions. Mike
Oct 15 2017
parent reply Michael V. Franklin <slavo5150 yahoo.com> writes:
On Monday, 16 October 2017 at 03:29:03 UTC, Michael V. Franklin 
wrote:

 My experience says that BountySource almost doesn't help.
It works if the bounty is worth someone sacrificing their free time to do the work. For example, I'd attempt fixing the bug if the bounty were greater than $200, but I don't know if I'd be successful, as I've only just started working working with the DMD source code.
In fact, you might want to propose matching bounty from the community on this specific bug to encourage funding. For example, make an announcement on the forum that anyone who places a bounty on the bug in question will receive a matching contribution from you. Maybe that might raise the bounty high enough to get someone qualified to fix the bug. Or maybe not; it's just an idea that occurred to me. Mike
Oct 15 2017
parent reply ketmar <ketmar ketmar.no-ip.org> writes:
Michael V. Franklin wrote:

 In fact, you might want to propose matching bounty from the community on 
 this specific bug to encourage funding.  For example, make an 
 announcement on the forum that anyone who places a bounty on the bug in 
 question will receive a matching contribution from you.  Maybe that might 
 raise the bounty high enough to get someone qualified to fix the bug.  Or 
 maybe not; it's just an idea that occurred to me.
judging from my several decades of expirience, bounties almost never works. there are alot of reasons for that, but the fact still stands: it is *almost* impossible to make something happen with boundy. it may work by accident ;-), but i myself wouldn't count on that. either bounty is too small ("hey, my time worth much more! i'd better spend it playing videogames!"), or it is too big ("hey, this is a Really Huge Problem, if somebody wants to pay than much! that means that i'll inevitably spend more time on that, and... the bounty is too small. oops." ;-). but one can hire a contractor to fix some specific problem. this is much easier, and almost usually works as people expected: there are clearly specified goals, a payment, a timeline and such. both parties know what exactly they want, and can control the whole process.
Oct 15 2017
parent Arun Chandrasekaran <aruncxy gmail.com> writes:
On Monday, 16 October 2017 at 03:49:18 UTC, ketmar wrote:
 Michael V. Franklin wrote:

 [...]
judging from my several decades of expirience, bounties almost never works. there are alot of reasons for that, but the fact still stands: it is *almost* impossible to make something happen with boundy. it may work by accident ;-), but i myself wouldn't count on that. either bounty is too small ("hey, my time worth much more! i'd better spend it playing videogames!"), or it is too big ("hey, this is a Really Huge Problem, if somebody wants to pay than much! that means that i'll inevitably spend more time on that, and... the bounty is too small. oops." ;-). [...]
True, that's how Eric Niebler gets to work on Range V1, V2, V3 as he was the only hired programmer by ISO CPP.
Oct 16 2017
prev sibling parent Temtaime <temtaime gmail.com> writes:
On Friday, 13 October 2017 at 11:21:48 UTC, Biotronic wrote:
 On Friday, 13 October 2017 at 10:35:56 UTC, Jack Applegame 
 wrote:
 Compiler creates struct on the stack and silently (without 
 postblitting and destruction old object) moves it to another 
 address. Is it normal? I don't think so.
It is. Structs have no identity, and the compiler/GC/whatever is free to copy and/or move them about as it sees fit (as long as there is ostensibly only one - no duplicate constructor/destructor calls, no desynching of state). That's why the documentation[1] says not to have internal pointers in structs.
 WAT??? Compiler creates struct on the stack copies it without 
 postblitting and destructs both objects.
Now this looks like a real bug. There should be a this(this) call in there.
 Can I donate to the D Foundation and that my donations would 
 be aimed at fixing exactly these bugs?
BountySource[2] lets you do basically exactly that. [1]: https://dlang.org/spec/garbage.html, "Do not have pointers in a struct instance that point back to the same instance." [2]: https://www.bountysource.com/
What are the advantages of this weird behavior ? Also if the object is finally moved then why to call ctor not on the moved object ? [1] states that i cannot save the pointer inside the struct on the same struct(because GC can move objects in the memory, but in the example there's no gc as objects are on the stack), but what if i put &this to some global variable ? It should work as expected, not being partly moved. Postblit should be called as well as dtor of original object. 1 is a definitely a bug.
Oct 13 2017
prev sibling next sibling parent reply Dgame <r.schuett.1987 gmail.com> writes:
On Friday, 13 October 2017 at 10:35:56 UTC, Jack Applegame wrote:
 If you don't want to get the great PITA, never create temporary 
 objects in function parameters.
 I recently spent a whole day digging through my reference 
 counted containers library. But nasty bug was not there, but in 
 the compiler.

 Look at this: https://glot.io/snippets/eui2l8ov0r

 Result:
 Bar.this(int): 7FFD3D60CD38
 fun: 7FFD3D60CD20
 Bar.~this(): 7FFD3D60CD20
Compiler creates struct on the stack and silently (without postblitting and destruction old object) moves it to another address. Is it normal? I don't think so. But that's not the most fun. Look at this: https://glot.io/snippets/eui2pjrwvi Result:
 Bar.this(int): 7FFF87DD2D31
 fun: 7FFF87DD2CE0
 Bar.~this(): 7FFF87DD2CE0
 Bar.~this(): 7FFF87DD2D31
WAT??? Compiler creates struct on the stack copies it without postblitting and destructs both objects. But if you create the structure before calling the function, then all will be well: https://glot.io/snippets/eui2vn2bu1 All this greatly angered me because there are several issues related wrong struct construction and destruction in the bugtracker. Because of these bugs my low level libraries full of strange hacks. I want to ask. How you guys are going to create a reliable RC library, if such fundamental bugs hang in the issue tracker for months and years. And instead of fixing them, you develop new minor bells and whistles. See: https://issues.dlang.org/buglist.cgi?quicksearch=destructor Since I myself can't fix such bugs (my knowledge in this area are extremely small), I have a question to Andrei Alexandrescu: Can I donate to the D Foundation and that my donations would be aimed at fixing exactly these bugs?
Interesting. If you remove the CTor in Foo it works again.
Oct 13 2017
parent reply Jack Applegame <japplegame gmail.com> writes:
On Friday, 13 October 2017 at 12:03:55 UTC, Dgame wrote:
 Interesting. If you remove the CTor in Foo it works again.
If you remove DTor it works again too. :)
Oct 13 2017
parent reply Dgame <r.schuett.1987 gmail.com> writes:
On Friday, 13 October 2017 at 12:08:00 UTC, Jack Applegame wrote:
 On Friday, 13 October 2017 at 12:03:55 UTC, Dgame wrote:
 Interesting. If you remove the CTor in Foo it works again.
If you remove DTor it works again too. :)
That's one of these times where it would be helpful to see the generated AST.
Oct 13 2017
parent Steven Schveighoffer <schveiguy yahoo.com> writes:
On 10/13/17 8:56 AM, Dgame wrote:
 On Friday, 13 October 2017 at 12:08:00 UTC, Jack Applegame wrote:
 On Friday, 13 October 2017 at 12:03:55 UTC, Dgame wrote:
 Interesting. If you remove the CTor in Foo it works again.
If you remove DTor it works again too. :)
That's one of these times where it would be helpful to see the generated AST.
dmd has this feature: -vcg-ast. I already have tried it, and looks like there is no call to the dtor that matches the output. I think it's a bug in the compiler. -Steve
Oct 13 2017
prev sibling parent reply John Burton <john.burton jbmail.com> writes:
On Friday, 13 October 2017 at 10:35:56 UTC, Jack Applegame wrote:
 If you don't want to get the great PITA, never create temporary 
 objects in function parameters.
 I recently spent a whole day digging through my reference 
 counted containers library. But nasty bug was not there, but in 
 the compiler.

 Look at this: https://glot.io/snippets/eui2l8ov0r

 Result:
 Bar.this(int): 7FFD3D60CD38
 fun: 7FFD3D60CD20
 Bar.~this(): 7FFD3D60CD20
Compiler creates struct on the stack and silently (without postblitting and destruction old object) moves it to another address. Is it normal? I don't think so. But that's not the most fun. Look at this: https://glot.io/snippets/eui2pjrwvi Result:
 Bar.this(int): 7FFF87DD2D31
 fun: 7FFF87DD2CE0
 Bar.~this(): 7FFF87DD2CE0
 Bar.~this(): 7FFF87DD2D31
WAT??? Compiler creates struct on the stack copies it without postblitting and destructs both objects. But if you create the structure before calling the function, then all will be well: https://glot.io/snippets/eui2vn2bu1 All this greatly angered me because there are several issues related wrong struct construction and destruction in the bugtracker. Because of these bugs my low level libraries full of strange hacks. I want to ask. How you guys are going to create a reliable RC library, if such fundamental bugs hang in the issue tracker for months and years. And instead of fixing them, you develop new minor bells and whistles. See: https://issues.dlang.org/buglist.cgi?quicksearch=destructor Since I myself can't fix such bugs (my knowledge in this area are extremely small), I have a question to Andrei Alexandrescu: Can I donate to the D Foundation and that my donations would be aimed at fixing exactly these bugs?
Is this a bug? Reading the chapter "7.1.3.5 They Whys of this(this)" in my D Programming Language book it says that the compiler is free to elide the call to this(this) when it can prove that the source of the copy will not be used after the call. The explanations there make some sense to me. Is this actually working as intended? (Just not how you'd hope it works)?
Oct 17 2017
parent reply Steven Schveighoffer <schveiguy yahoo.com> writes:
On 10/17/17 12:27 PM, John Burton wrote:
 On Friday, 13 October 2017 at 10:35:56 UTC, Jack Applegame wrote:
 If you don't want to get the great PITA, never create temporary 
 objects in function parameters.
 I recently spent a whole day digging through my reference counted 
 containers library. But nasty bug was not there, but in the compiler.

 Look at this: https://glot.io/snippets/eui2l8ov0r

 Result:
 Bar.this(int): 7FFD3D60CD38
 fun: 7FFD3D60CD20
 Bar.~this(): 7FFD3D60CD20
Compiler creates struct on the stack and silently (without postblitting and destruction old object) moves it to another address. Is it normal? I don't think so. But that's not the most fun. Look at this: https://glot.io/snippets/eui2pjrwvi Result:
 Bar.this(int): 7FFF87DD2D31
 fun: 7FFF87DD2CE0
 Bar.~this(): 7FFF87DD2CE0
 Bar.~this(): 7FFF87DD2D31
WAT??? Compiler creates struct on the stack copies it without postblitting and destructs both objects. But if you create the structure before calling the function, then all will be well: https://glot.io/snippets/eui2vn2bu1 All this greatly angered me because there are several issues related wrong struct construction and destruction in the bugtracker. Because of these bugs my low level libraries full of strange hacks. I want to ask. How you guys are going to create a reliable RC library, if such fundamental bugs hang in the issue tracker for months and years. And instead of fixing them, you develop new minor bells and whistles. See: https://issues.dlang.org/buglist.cgi?quicksearch=destructor Since I myself can't fix such bugs (my knowledge in this area are extremely small), I have a question to Andrei Alexandrescu: Can I donate to the D Foundation and that my donations would be aimed at fixing exactly these bugs?
Is this a bug? Reading the chapter "7.1.3.5 They Whys of this(this)" in my D Programming Language book it says that the compiler is free to elide the call to this(this) when it can prove that the source of the copy will not be used after the call.
It is allowed to, yes, and it should in this case.
 The explanations there make some sense to me.
 
 Is this actually working as intended? (Just not how you'd hope it works)?
No, if a postblit is called, then an equivalent destructor should be called as well. The number of constructors + postblit calls should equal the number of destructor calls. Otherwise, you can't do things reliably like reference counting. In this case, an extra destructor call is made without a corresponding postblit or constructor. -Steve
Oct 17 2017
parent Mike Franklin <slavo5150 yahoo.com> writes:
On Tuesday, 17 October 2017 at 19:00:38 UTC, Steven Schveighoffer 
wrote:

 In this case, an extra destructor call is made without a 
 corresponding postblit or constructor.

 -Steve
https://issues.dlang.org/show_bug.cgi?id=18050
Dec 08 2017