www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - crash when using &this in struct constructor

reply Eric <geachte.eric gmail.com> writes:
This makes the compiler crash. Is it illegal code?

struct List {
   private List* head;
   private List* tail;

   this(int x) {
     head = null;
     tail = &this; // <-- crasher
   }
}

List2 ls = 2;
Jul 16 2018
next sibling parent Eric <geachte.eric gmail.com> writes:
Pasted slightly wrong code, last line should be:
List ls = 2;

Question still stands.
Jul 16 2018
prev sibling next sibling parent reply Adam D. Ruppe <destructionator gmail.com> writes:
On Monday, 16 July 2018 at 22:08:34 UTC, Eric wrote:
 This makes the compiler crash. Is it illegal code?
Yes, a struct can be moved at any time by the compiler which means pointers to it can be invalidated at random. Unless you always allocate it externally yourself...
Jul 16 2018
parent Eric <geachte.eric gmail.com> writes:
On Monday, 16 July 2018 at 22:16:10 UTC, Adam D. Ruppe wrote:
 On Monday, 16 July 2018 at 22:08:34 UTC, Eric wrote:
 This makes the compiler crash. Is it illegal code?
Yes, a struct can be moved at any time by the compiler which means pointers to it can be invalidated at random. Unless you always allocate it externally yourself...
I know that. At the moment I disable the postblit and use an init(): class Test { List ls; this() { ls.init(); } } But I want to be able to write something less verbose like: class Test { List ls = 1; } And I was hoping a this(int) constructor would happen in place, not move things around.
Jul 16 2018
prev sibling next sibling parent reply "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Mon, Jul 16, 2018 at 10:08:34PM +0000, Eric via Digitalmars-d-learn wrote:
 This makes the compiler crash. Is it illegal code?
 
 struct List {
   private List* head;
   private List* tail;
 
   this(int x) {
     head = null;
     tail = &this; // <-- crasher
   }
 }
 
 List2 ls = 2;
It's not illegal per se, but a very, very bad idea in general, because in D, structs are expected to be int-like POD values that can be freely copied/moved around by the compiler. More specifically, when structs are passed into functions or returned from functions, they may be moved around. Which means internal pointers will wind up being wrong. This can be somewhat alleviated with a postblit ctor, but it doesn't cover all the cases, and the above code looks like one of the cases where it will likely not cover all cases. So yeah, you're probably getting a dangling pointer because of this. If you need something that doesn't move around, either allocate the struct on the heap using `new`, or use classes instead. Note that while the former will work, it will still require care, because passing the resulting struct around will pass it by value, and you end up with the same dangling pointer problem again. So you really want to be using classes for this. Or rethink your algorithms so that they don't depend on having internal pointers. T -- Give me some fresh salted fish, please.
Jul 16 2018
parent reply baz dlang-community <b2.temp gmx.com> writes:
On Monday, 16 July 2018 at 22:21:12 UTC, H. S. Teoh wrote:
 On Mon, Jul 16, 2018 at 10:08:34PM +0000, Eric via 
 Digitalmars-d-learn wrote:
 [...]
It's not illegal per se, but a very, very bad idea in general, because in D, structs are expected to be int-like POD values that can be freely copied/moved around by the compiler. More specifically, when structs are passed into functions or returned from functions, they may be moved around. Which means internal pointers will wind up being wrong. [...]
Moving doesn't seem to be the issue here. Despite of the ICE, this code shouldn't compile, unless "&this" is allowed at compile-time.
Jul 18 2018
parent reply baz <b2.temp gmx.com> writes:
On Wednesday, 18 July 2018 at 11:27:33 UTC, baz dlang-community 
wrote:
 On Monday, 16 July 2018 at 22:21:12 UTC, H. S. Teoh wrote:
 On Mon, Jul 16, 2018 at 10:08:34PM +0000, Eric via 
 Digitalmars-d-learn wrote:
 [...]
It's not illegal per se, but a very, very bad idea in general, because in D, structs are expected to be int-like POD values that can be freely copied/moved around by the compiler. More specifically, when structs are passed into functions or returned from functions, they may be moved around. Which means internal pointers will wind up being wrong. [...]
Moving doesn't seem to be the issue here. Despite of the ICE, this code shouldn't compile, unless "&this" is allowed at compile-time.
still with .init() trick this works, so im' not super sure...
Jul 18 2018
parent reply baz <b2.temp gmx.com> writes:
On Wednesday, 18 July 2018 at 11:35:40 UTC, baz wrote:
 On Wednesday, 18 July 2018 at 11:27:33 UTC, baz dlang-community 
 wrote:
 On Monday, 16 July 2018 at 22:21:12 UTC, H. S. Teoh wrote:
 On Mon, Jul 16, 2018 at 10:08:34PM +0000, Eric via 
 Digitalmars-d-learn wrote:
 [...]
It's not illegal per se, but a very, very bad idea in general, because in D, structs are expected to be int-like POD values that can be freely copied/moved around by the compiler. More specifically, when structs are passed into functions or returned from functions, they may be moved around. Which means internal pointers will wind up being wrong. [...]
Moving doesn't seem to be the issue here. Despite of the ICE, this code shouldn't compile, unless "&this" is allowed at compile-time.
still with .init() trick this works, so im' not super sure...
NVM the .init() trick. Specs are clear : it's a global so it's evaluated at compile time (https://dlang.org/spec/declaration.html#global_static_init) Example code should not compile.
Jul 18 2018
parent Eric <geachte.eric gmail.com> writes:
On Wednesday, 18 July 2018 at 12:10:18 UTC, baz wrote:

 Specs are clear : it's a global so it's evaluated at compile 
 time 
 (https://dlang.org/spec/declaration.html#global_static_init)

 Example code should not compile.
Indeed. Inside a function it does actually work. And ofcourse for class Test { List ls = 1; } it's going to make a static initializer which is then copied during construction of Test, so that's never going to work with the &this.
Jul 18 2018
prev sibling parent =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 07/16/2018 03:08 PM, Eric wrote:
 This makes the compiler crash.
Always a compiler bug: https://issues.dlang.org/show_bug.cgi?id=19089 Ali
Jul 16 2018