Thread overview | ||||||||
---|---|---|---|---|---|---|---|---|
|
June 08 [Issue 23164] [REG 2.097] Infinite loop on assertion failure + DMD moves struct with copy constructor | ||||
---|---|---|---|---|
| ||||
https://issues.dlang.org/show_bug.cgi?id=23164 RazvanN <razvan.nitu1305@gmail.com> changed: What |Removed |Added ---------------------------------------------------------------------------- Keywords| |backend CC| |razvan.nitu1305@gmail.com -- |
July 08 [Issue 23164] [REG 2.097] Infinite loop on assertion failure + DMD moves struct with copy constructor | ||||
---|---|---|---|---|
| ||||
https://issues.dlang.org/show_bug.cgi?id=23164 Walter Bright <bugzilla@digitalmars.com> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |bugzilla@digitalmars.com --- Comment #1 from Walter Bright <bugzilla@digitalmars.com> --- Remember that D does not allow internal pointers to members. -- |
July 08 [Issue 23164] [REG 2.097] Infinite loop on assertion failure + DMD moves struct with copy constructor | ||||
---|---|---|---|---|
| ||||
https://issues.dlang.org/show_bug.cgi?id=23164 --- Comment #2 from Walter Bright <bugzilla@digitalmars.com> --- If I add @safe and compile with -preview=dip1000, I get: test23164.d(15): Error: address of variable `this` assigned to `this` with longer lifetime test23164.d(22): Error: address of variable `this` assigned to `this` with longer lifetime Line 15 is: this.ptr = &this; in the constructor Line 22 is: this.ptr = &this; in the copy constructor -- |
July 08 [Issue 23164] [REG 2.097] Infinite loop on assertion failure + DMD moves struct with copy constructor | ||||
---|---|---|---|---|
| ||||
https://issues.dlang.org/show_bug.cgi?id=23164 --- Comment #3 from Walter Bright <bugzilla@digitalmars.com> --- I find the `auto ref` parameter suspicious. What are you expecting to happen there? Do you expect it to be passed by ref or by value? It doesn't compile with making it just `ref`, so simply removing `auto ref` produces the same result (infinite loop assert in the destructor). But, passing it by value means another constructor call, and another destructor call. I'm not sure what you're expecting to happen here. I suspect the problem is with the `auto ref`. Copy constructors should be passing their rvalue by ref, amirite? -- |
July 08 [Issue 23164] [REG 2.097] Infinite loop on assertion failure + DMD moves struct with copy constructor | ||||
---|---|---|---|---|
| ||||
https://issues.dlang.org/show_bug.cgi?id=23164 --- Comment #4 from Mathias LANG <pro.mathias.lang@gmail.com> --- > Remember that D does not allow internal pointers to members. If memory serves me well, Andrei mentioned a few years ago that this position is no longer tenable. Not supporting internal pointers means users cannot interface with `std::string`, which is a huge blow too C++ interop. And internal pointers are one of the reasons we got the copy constructors, aren't they ? > I find the `auto ref` parameter suspicious. What are you expecting to happen there? Do you expect it to be passed by ref or by value? I expect a single constructor call for a value constructed in the caller. In other word, I expect: ``` tmp = std_string(42); ``` and: ``` auto someLValue = std_string(42); tmp = someLValue; ``` to only call `std_string` constructor once. If I don't use `auto ref` (pass by value), the code will compile for both snippets above but in the case of `someLValue`, it will call the constructor one more time. If I use plain `ref`, the code will not compile for the first snipped (passing a rvalue). Note that the original test case was using `in`, which is just `ref` accepting rvalue, so I doubt `auto ref` is at fault here (especially considering LDC and GDC don't have the bug, only DMD does). -- |
July 09 [Issue 23164] [REG 2.097] Infinite loop on assertion failure + DMD moves struct with copy constructor | ||||
---|---|---|---|---|
| ||||
https://issues.dlang.org/show_bug.cgi?id=23164 Iain Buclaw <ibuclaw@gdcproject.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |ibuclaw@gdcproject.org --- Comment #5 from Iain Buclaw <ibuclaw@gdcproject.org> --- (In reply to Mathias LANG from comment #0) > The following code shows 2 assertions failures in v2.096.1, an infinite loop > on v2.097.0: > ``` --snip-- > ~this () > { > assert(this.ptr is &this); > } --snip-- > ``` > > The original test was to see whether or not DMD would move a struct with a copy constructor. The above code compiles and runs fine with LDC & GDC, but asserts with DMD. To explain GDC behaviour. *Because* there is a destructor (or postblit, copy constructor, or anything that would other make the struct non-trivially copyable) then the type is *always* *implicitly* passed and returned by invisible reference. The right reduction would be this: ``` struct std_string { std_string* ptr; ulong[3] data; this (ulong data) { this.data[] = data; this.ptr = &this; } ~this () { } // GDC and LDC forces 'auto ref' to be 'ref', even when the // front-end decides to drop the 'ref' from the signature. ref std_string opAssign()(const auto ref std_string rhs) { assert(rhs.ptr is &rhs); return this; } } void main () { std_string tmp; tmp = std_string(42); } ``` -- |
Copyright © 1999-2021 by the D Language Foundation