May 10, 2018 Re: Extra .tupleof field in structs with disabled postblit blocks non-GC-allocation trait | ||||
---|---|---|---|---|
| ||||
Posted in reply to Per Nordlöw | On Thursday, 10 May 2018 at 11:06:06 UTC, Per Nordlöw wrote:
> On Wednesday, 9 May 2018 at 21:09:12 UTC, Meta wrote:
>> It's a context pointer to the enclosing function/object/struct. Mark the struct as static to get rid of it.
>
> Ok, but why an extra void* for `S.tupleof` and not for `T.tupleof` which is also scoped inside a unittest?
I'm guessing T is a POD, so it doesn't need a context pointer, whereas S is not counted as a POD since a member function was @disabled.
|
May 10, 2018 Re: Extra .tupleof field in structs with disabled postblit blocks non-GC-allocation trait | ||||
---|---|---|---|---|
| ||||
Posted in reply to Uknown | On Thursday, 10 May 2018 at 12:55:36 UTC, Uknown wrote: > On Thursday, 10 May 2018 at 11:06:06 UTC, Per Nordlöw wrote: >> On Wednesday, 9 May 2018 at 21:09:12 UTC, Meta wrote: >>> It's a context pointer to the enclosing function/object/struct. Mark the struct as static to get rid of it. >> >> Ok, but why an extra void* for `S.tupleof` and not for `T.tupleof` which is also scoped inside a unittest? > > I'm guessing T is a POD, so it doesn't need a context pointer, whereas S is not counted as a POD since a member function was @disabled. Yes, exactly. From my tests, if you add _any_ member method to a struct, it becomes non-POD. When you think about it, this makes perfect sense, as there's no possible way to access anything through a context pointer if there is no executable code within the struct's scope. As far an @disabled postblit: Plain Old Data A struct or union is Plain Old Data (POD) if it meets the following criteria: it is not nested it has no postblits, destructors, or assignment operators it has no ref fields or fields that are themselves non-PO https://docarchives.dlang.io/v2.079.0/spec/struct.html#POD Now if you do this: struct R { @disable this(this); int* _ptr; } unittest { struct S { @disable this(this); int* _ptr; } struct T { int* _ptr; } pragma(msg, "R: ", typeof(R.tupleof)); pragma(msg, __traits(allMembers, R)); pragma(msg, "S: ", typeof(S.tupleof)); pragma(msg, __traits(allMembers, S)); pragma(msg, "T: ", typeof(T.tupleof)); pragma(msg, __traits(allMembers, T)); } It prints: R: (int*) tuple("__postblit", "_ptr", "__xpostblit", "opAssign") S: (int*, void*) tuple("__postblit", "_ptr", "this", "__xpostblit", "opAssign") T: (int*) tuple("_ptr") So it looks like disabling a struct's postblit actually counts as having a __postblit and __xpostblit function (don't ask me why), in addition to a construction and opAssign... no idea why, and maybe this is a bug, but I bet there's a good reason for it. Anyway, as per my first point, this means it'll need a context pointer unless you mark the struct as static. |
May 11, 2018 Re: Extra .tupleof field in structs with disabled postblit blocks non-GC-allocation trait | ||||
---|---|---|---|---|
| ||||
Posted in reply to Meta | On Thursday, 10 May 2018 at 19:14:39 UTC, Meta wrote: > > So it looks like disabling a struct's postblit actually counts as having a __postblit and __xpostblit function (don't ask me why), in addition to a construction and opAssign... no idea why, and maybe this is a bug, but I bet there's a good reason for it. https://issues.dlang.org/show_bug.cgi?id=18628 -Johan |
Copyright © 1999-2021 by the D Language Foundation