www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Inconsistency between `AllMembers` and `hasMember`

reply drug <drug2004 bk.ru> writes:
https://run.dlang.io/is/IygU5D

AllMembers states that struct S contains "this" member, but hasMember 
negates it. Is it bug or misusing?
Nov 17 2018
next sibling parent reply Adam D. Ruppe <destructionator gmail.com> writes:
On Saturday, 17 November 2018 at 20:54:24 UTC, drug wrote:
 https://run.dlang.io/is/IygU5D

 AllMembers states that struct S contains "this" member, but 
 hasMember negates it. Is it bug or misusing?
I'm not sure what it is supposed to do, but since this is kinda special - it is a keyword for the constructor - I wouldn't expect it to be accessible this way in any reliable manner...
Nov 17 2018
parent reply drug <drug2004 bk.ru> writes:
On 18.11.2018 0:09, Adam D. Ruppe wrote:
 On Saturday, 17 November 2018 at 20:54:24 UTC, drug wrote:
 https://run.dlang.io/is/IygU5D

 AllMembers states that struct S contains "this" member, but hasMember 
 negates it. Is it bug or misusing?
I'm not sure what it is supposed to do, but since this is kinda special - it is a keyword for the constructor - I wouldn't expect it to be accessible this way in any reliable manner...
Well, this is another question. I mean that if AllMembers returns something it should exist. If it is special member and can not be accesible AllMembers shouldn't return it. Another problem I'm trying to resolve is that if I define struct S outside of unittest or inside of unittest but using static qualifier AllMembers does not return "this". Also if struct S do not have methods AllMembers also doesn't return "this". It looks strange for me, but first of all it complicates my code.
Nov 17 2018
parent reply Adam D. Ruppe <destructionator gmail.com> writes:
On Saturday, 17 November 2018 at 21:33:37 UTC, drug wrote:
 Another problem I'm trying to resolve is that if I define 
 struct S outside of unittest or inside of unittest but using 
 static qualifier AllMembers does not return "this". Also if 
 struct S do not have methods AllMembers also doesn't return 
 "this". It looks strange for me, but first of all it 
 complicates my code.
That's because the compiler passes it a hidden pointer to refer to the context outside. The compiler could perhaps be smarter about it, and see if those methods actually refer to the context, but it seems to simply say if the method is there, it might refer to it and it adds the context pointer (note that S.sizeof increases too) and a magic constructor to set it.
Nov 17 2018
parent reply drug <drug2004 bk.ru> writes:
On 18.11.2018 1:26, Adam D. Ruppe wrote:
 
 That's because the compiler passes it a hidden pointer to refer to the 
 context outside. The compiler could perhaps be smarter about it, and see 
 if those methods actually refer to the context, but it seems to simply 
 say if the method is there, it might refer to it and it adds the context 
 pointer (note that S.sizeof increases too) and a magic constructor to 
 set it.
Well, if "this" means hidden pointer then it never should be returned by AllMembers at all, isn't it?
Nov 17 2018
parent reply Stanislav Blinov <stanislav.blinov gmail.com> writes:
On Sunday, 18 November 2018 at 00:51:51 UTC, drug wrote:
 On 18.11.2018 1:26, Adam D. Ruppe wrote:
 
 That's because the compiler passes it a hidden pointer to 
 refer to the context outside. The compiler could perhaps be 
 smarter about it, and see if those methods actually refer to 
 the context, but it seems to simply say if the method is 
 there, it might refer to it and it adds the context pointer 
 (note that S.sizeof increases too) and a magic constructor to 
 set it.
Well, if "this" means hidden pointer then it never should be returned by AllMembers at all, isn't it?
It's only "hidden" in that there's no symbol to access it. But you can still access it via .tupleof, and it still of course affects the ABI (i.e. S.sizeof is always at least pointer size when S is nested). If you want to iterate fields, .tupleof is a better way to do it. As for that hidden pointer, you can just test with __traits(isNested, S) whether that's present, and just don't look at the last field.
Nov 17 2018
next sibling parent reply bauss <jj_1337 live.dk> writes:
On Sunday, 18 November 2018 at 02:37:13 UTC, Stanislav Blinov 
wrote:
 On Sunday, 18 November 2018 at 00:51:51 UTC, drug wrote:
 On 18.11.2018 1:26, Adam D. Ruppe wrote:
 
 That's because the compiler passes it a hidden pointer to 
 refer to the context outside. The compiler could perhaps be 
 smarter about it, and see if those methods actually refer to 
 the context, but it seems to simply say if the method is 
 there, it might refer to it and it adds the context pointer 
 (note that S.sizeof increases too) and a magic constructor to 
 set it.
Well, if "this" means hidden pointer then it never should be returned by AllMembers at all, isn't it?
It's only "hidden" in that there's no symbol to access it. But you can still access it via .tupleof, and it still of course affects the ABI (i.e. S.sizeof is always at least pointer size when S is nested). If you want to iterate fields, .tupleof is a better way to do it. As for that hidden pointer, you can just test with __traits(isNested, S) whether that's present, and just don't look at the last field.
But in that case shouldn't you be able to tell whether it has it or not through hasMember?
Nov 18 2018
parent Stanislav Blinov <stanislav.blinov gmail.com> writes:
On Sunday, 18 November 2018 at 09:10:57 UTC, bauss wrote:
 On Sunday, 18 November 2018 at 02:37:13 UTC, Stanislav Blinov 
 wrote:
 It's only "hidden" in that there's no symbol to access it...
 But in that case shouldn't you be able to tell whether it has 
 it or not through hasMember?
Yah, a case for inconsistency could be made here. IMHO it should just have some reserved name like __context.
Nov 18 2018
prev sibling parent drug <drug2004 bk.ru> writes:
On 18.11.2018 5:37, Stanislav Blinov wrote:
 
 It's only "hidden" in that there's no symbol to access it. But you can 
 still access it via .tupleof, and it still of course affects the ABI 
 (i.e. S.sizeof is always at least pointer size when S is nested).
 If you want to iterate fields, .tupleof is a better way to do it. As for 
 that hidden pointer, you can just test with __traits(isNested, S) 
 whether that's present, and just don't look at the last field.
But what is the reason for someone to use this pointer even via .tupleof? I still think AllMember shouldn't return it at all. Of course I can filter it using isNested or just comparing with "this" leteral during iteration. But it complicates things I believe. P.S. using isNested seems to be more portable solution than comparing with leteral but is this pointer always the last element in AllMember trait result?
Nov 18 2018
prev sibling parent Stanislav Blinov <stanislav.blinov gmail.com> writes:
Reported:

https://issues.dlang.org/show_bug.cgi?id=19410
Nov 18 2018