Thread overview | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
May 09, 2018 Extra .tupleof field in structs with disabled postblit blocks non-GC-allocation trait | ||||
---|---|---|---|---|
| ||||
Why (on earth) does struct S { @disable this(this); int* _ptr; } pragma(msg, typeof(S.tupleof)); prints (int*, void*) when struct S { int* _ptr; } pragma(msg, typeof(S.tupleof)); prints (int*) ?!!! This prevents the trait `mustAddGCRangeOfStructOrUnion` [1] from detecting when a container with manual memory management doesn't have to be scanned by the GC as in, for instance, enum NoGc; struct S { @disable this(this); // disable S postlib @NoGc int* _ptr; } static assert(!mustAddGCRangeOfStructOrUnion!S); // is false when postblit of `S` is disabled [1] https://github.com/nordlow/phobos-next/blob/master/src/gc_traits.d#L81 |
May 09, 2018 Re: Extra .tupleof field in structs with disabled postblit blocks non-GC-allocation trait | ||||
---|---|---|---|---|
| ||||
Posted in reply to Per Nordlöw | On Wednesday, 9 May 2018 at 14:07:37 UTC, Per Nordlöw wrote:
> This prevents the trait `mustAddGCRangeOfStructOrUnion` [1] from detecting when a container with manual memory management doesn't have to be scanned by the GC as in, for instance,
>
> enum NoGc;
> struct S
> {
> @disable this(this); // disable S postlib
> @NoGc int* _ptr;
> }
> static assert(!mustAddGCRangeOfStructOrUnion!S); // is false when postblit of `S` is disabled
>
> [1] https://github.com/nordlow/phobos-next/blob/master/src/gc_traits.d#L81
Can we statically check if the postblit has been disabled via
@disable this(this);
?
If so, we can temporarily modify the trait to exclude the last `void*` member of the `S.tuple`. Given that it's always added as the last member.
|
May 09, 2018 Re: Extra .tupleof field in structs with disabled postblit blocks non-GC-allocation trait | ||||
---|---|---|---|---|
| ||||
Posted in reply to Per Nordlöw | On Wednesday, 9 May 2018 at 14:20:41 UTC, Per Nordlöw wrote:
> If so, we can temporarily modify the trait to exclude the last `void*` member of the `S.tuple`. Given that it's always added as the last member.
Note that `std.traits.isCopyable!S` cannot be used, because it will return true when `S` has uncopyable members regardless of whether S.tupleof have any extra void* element or not (because of S's disabled postblit).
|
May 09, 2018 Re: Extra .tupleof field in structs with disabled postblit blocks non-GC-allocation trait | ||||
---|---|---|---|---|
| ||||
Posted in reply to Per Nordlöw | On Wednesday, 9 May 2018 at 14:20:41 UTC, Per Nordlöw wrote:
> If so, we can temporarily modify the trait to exclude the last `void*` member of the `S.tuple`. Given that it's always added as the last member.
Also note that
pragma(msg, __traits(isDisabled, S.this(this)));
fails to compile as
Error: identifier expected following `.`, not `this`
|
May 09, 2018 Re: Extra .tupleof field in structs with disabled postblit blocks non-GC-allocation trait | ||||
---|---|---|---|---|
| ||||
Posted in reply to Per Nordlöw | On Wednesday, 9 May 2018 at 14:34:02 UTC, Per Nordlöw wrote:
> On Wednesday, 9 May 2018 at 14:20:41 UTC, Per Nordlöw wrote:
>> If so, we can temporarily modify the trait to exclude the last `void*` member of the `S.tuple`. Given that it's always added as the last member.
>
> Also note that
>
> pragma(msg, __traits(isDisabled, S.this(this)));
>
> fails to compile as
>
> Error: identifier expected following `.`, not `this`
Ahh, but both
pragma(msg, __traits(isDisabled, S.__postblit));
pragma(msg, __traits(isDisabled, S.__xpostblit));
prints true for a struct with `@disable this(this);`
Which one should I pick to check if last element of `S.tupleof` should be discarded?
|
May 09, 2018 Re: Extra .tupleof field in structs with disabled postblit blocks non-GC-allocation trait | ||||
---|---|---|---|---|
| ||||
Posted in reply to Per Nordlöw | On Wednesday, 9 May 2018 at 14:36:38 UTC, Per Nordlöw wrote: > On Wednesday, 9 May 2018 at 14:34:02 UTC, Per Nordlöw wrote: >> On Wednesday, 9 May 2018 at 14:20:41 UTC, Per Nordlöw wrote: >>> If so, we can temporarily modify the trait to exclude the last `void*` member of the `S.tuple`. Given that it's always added as the last member. >> >> Also note that >> >> pragma(msg, __traits(isDisabled, S.this(this))); >> >> fails to compile as >> >> Error: identifier expected following `.`, not `this` > > Ahh, but both > > pragma(msg, __traits(isDisabled, S.__postblit)); > pragma(msg, __traits(isDisabled, S.__xpostblit)); > > prints true for a struct with `@disable this(this);` > > Which one should I pick to check if last element of `S.tupleof` should be discarded? Managed to put together the hack private template mustAddGCRangeOfStructOrUnion(T) if (is(T == struct) || is(T == union)) { import std.traits : hasUDA; import std.meta : anySatisfy; static if (__traits(hasMember, T, "__postblit")) { static if (__traits(isDisabled, T.__postblit)) { enum mustAddGCRangeOfStructOrUnion = anySatisfy!(mustAddGCRangeOfMember, T.tupleof[0 .. $ - 1]); } else { enum mustAddGCRangeOfStructOrUnion = anySatisfy!(mustAddGCRangeOfMember, T.tupleof); } } else { enum mustAddGCRangeOfStructOrUnion = anySatisfy!(mustAddGCRangeOfMember, T.tupleof); } } defined here https://github.com/nordlow/phobos-next/blob/master/src/gc_traits.d#L81 Destroy. |
May 09, 2018 Re: Extra .tupleof field in structs with disabled postblit blocks non-GC-allocation trait | ||||
---|---|---|---|---|
| ||||
Posted in reply to Per Nordlöw | On Wednesday, 9 May 2018 at 14:07:37 UTC, Per Nordlöw wrote: > Why (on earth) does > > struct S > { > @disable this(this); > int* _ptr; > } > pragma(msg, typeof(S.tupleof)); > > prints > > (int*, void*) > > when > > struct S > { > int* _ptr; > } > pragma(msg, typeof(S.tupleof)); > > prints > > (int*) > > ?!!! I wasn't able to reproduce it on dmd-nightly: https://run.dlang.io/is/9wT8tH What version of the compiler are you using? |
May 09, 2018 Re: Extra .tupleof field in structs with disabled postblit blocks non-GC-allocation trait | ||||
---|---|---|---|---|
| ||||
Posted in reply to Meta | On Wednesday, 9 May 2018 at 17:52:48 UTC, Meta wrote:
> I wasn't able to reproduce it on dmd-nightly: https://run.dlang.io/is/9wT8tH
>
> What version of the compiler are you using?
Ahh, the struct needs to be in a unittest block for it to happen:
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, "S: ", typeof(S.tupleof));
pragma(msg, "T: ", typeof(T.tupleof));
}
prints
R: (int*)
S: (int*, void*)
T: (int*)
Why is that?
|
May 09, 2018 Re: Extra .tupleof field in structs with disabled postblit blocks non-GC-allocation trait | ||||
---|---|---|---|---|
| ||||
Posted in reply to Per Nordlöw | On Wednesday, 9 May 2018 at 18:04:40 UTC, Per Nordlöw wrote:
> On Wednesday, 9 May 2018 at 17:52:48 UTC, Meta wrote:
>> I wasn't able to reproduce it on dmd-nightly: https://run.dlang.io/is/9wT8tH
>>
>> What version of the compiler are you using?
>
> Ahh, the struct needs to be in a unittest block for it to happen:
>
> 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, "S: ", typeof(S.tupleof));
> pragma(msg, "T: ", typeof(T.tupleof));
> }
>
> prints
>
> R: (int*)
> S: (int*, void*)
> T: (int*)
>
> Why is that?
It's a context pointer to the enclosing function/object/struct. Mark the struct as static to get rid of it.
|
May 10, 2018 Re: Extra .tupleof field in structs with disabled postblit blocks non-GC-allocation trait | ||||
---|---|---|---|---|
| ||||
Posted in reply to Meta | 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?
|
Copyright © 1999-2021 by the D Language Foundation