www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - x.RC.__postblit () is not callable using argument types () const

reply "Dan" <dbdavidson yahoo.com> writes:
I've seen these type of errors often and usually the cause kind 
of jumps out. In this case I'm totally confused. Just trying to 
move from 2.06 to 2.061.

The code is: http://dpaste.dzfl.pl/f40e4d6f
and fails with the error in subject line. Observations:

- If "static if(1)" is changed to "static if(0)" it compiles
- If either _valuationHistory or goo member of BSItem is 
commented out it compiles.

I know the code is somewhat cryptic, but I've been using binary 
reduction comment in/out to try to narrow down this issue. I can 
not understand why an introduction of opEquals on a struct 
History with no relationship to RC causes an error to show for RC.

Thanks
Dan
Feb 04 2013
next sibling parent reply =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 02/04/2013 05:15 PM, Dan wrote:
 I've seen these type of errors often and usually the cause kind of jumps
 out. In this case I'm totally confused. Just trying to move from 2.06 to
 2.061.

 The code is: http://dpaste.dzfl.pl/f40e4d6f
 and fails with the error in subject line. Observations:

 - If "static if(1)" is changed to "static if(0)" it compiles
 - If either _valuationHistory or goo member of BSItem is commented out
 it compiles.

 I know the code is somewhat cryptic, but I've been using binary
 reduction comment in/out to try to narrow down this issue. I can not
 understand why an introduction of opEquals on a struct History with no
 relationship to RC causes an error to show for RC.

 Thanks
 Dan
Further reduced: struct History(V) { bool opEquals(const typeof(this) other) const { return true; } } struct RC { this(this) { _impl = _impl.dup; } string[] _impl; } struct BSItem { ValuationHistory _valuationHistory; RC[int] goo; } struct ValuationHistory { History!double _history; } void main() { } The problem is related to History.opEquals being 'const'. Remove that 'const' and the code compiles. This must be a (lack of) const-correctness issue. Ali
Feb 04 2013
parent reply "Dan" <dbdavidson yahoo.com> writes:
On Tuesday, 5 February 2013 at 01:38:54 UTC, Ali Çehreli wrote:

 Further reduced:
[snip]
 The problem is related to History.opEquals being 'const'. 
 Remove that 'const' and the code compiles. This must be a (lack 
 of) const-correctness issue.
Thanks Ali. If const is removed it will compile. I think you are correct it is a const issue, but I'm at a loss as to why? After all, it does not access anything and just returns true. I don't see any const issues. I can't say for sure, but I feel this worked fine in 2.06. What I find troubling is how long it took me cull the code to the offending and I still don't understand the error. Thanks Dan
Feb 04 2013
parent reply Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 2/5/13, Dan <dbdavidson yahoo.com> wrote:
 and I still don't understand the error.
The error in the git-head version is: Error: mutable method test.RC.__postblit is not callable using a const object Error: cannot modify struct this Slot with immutable members Yeah, it's still not very helpful. And I have no idea where "Slot" comes from.
Feb 04 2013
parent reply "Maxim Fomin" <maxim maxim-fomin.ru> writes:
On Tuesday, 5 February 2013 at 04:03:06 UTC, Andrej Mitrovic 
wrote:
 Yeah, it's still not very helpful. And I have no idea where 
 "Slot" comes from.
This is sub struct inside object.AssociativeArray.
Feb 05 2013
parent reply "Dan" <dbdavidson yahoo.com> writes:
On Tuesday, 5 February 2013 at 11:51:40 UTC, Maxim Fomin wrote:
 On Tuesday, 5 February 2013 at 04:03:06 UTC, Andrej Mitrovic 
 wrote:
 Yeah, it's still not very helpful. And I have no idea where 
 "Slot" comes from.
This is sub struct inside object.AssociativeArray.
Is it the case that this is a D compiler (or library) problem and there is no issue with the code? Or is there really a problem with it that I am not seeing? I gather from the responses the code looks fine, otherwise any misunderstanding would come up quickly. I feel like I have painted myself in a corner a bit. I love D's templates and am a fan of the compile time reflection. I have mixins that support things like OpEquals, OpCmp, toHash, etc. I try very hard to work with const correctly. mixin template OpEquals() { bool opEquals(const ref typeof(this) other) const { return typesDeepEqual(this, other); } bool opEquals(const typeof(this) other) const { return typesDeepEqual(this, other); } } This OpEquals in the sample was just this signature (which I have mixed in all over successfully) but with a 'return true'. I think this is the correct signature to use. If I understand correctly, were I to remove the const, then const instances may no longer call it - which is not a good change. Transitive const is more than just simple const, and obviously more is better ;-). Since "Slot" is mentioned and "object.AssociativeArrray" it sounds like there may be a const-correctness issue with associative array itself rather than this code? Before the move to 2.061 I had to cast away const on const(V[K]) to get length and to iterate over them. But why the link between History!double and RC[int] when they are totally unrelated? Well, the only relation is their aggregation in BSItem. Baffling. Any suggestions appreciated. Thanks Dan
Feb 05 2013
parent reply "Maxim Fomin" <maxim maxim-fomin.ru> writes:
On Tuesday, 5 February 2013 at 12:35:25 UTC, Dan wrote:
 Is it the case that this is a D compiler (or library) problem 
 and there is no issue with the code? Or is there really a 
 problem with it that I am not seeing? I gather from the 
 responses the code looks fine, otherwise any misunderstanding 
 would come up quickly.
This is compiler problem.
 Transitive const is more than just simple const, and obviously 
 more is better ;-). Since "Slot" is mentioned and 
 "object.AssociativeArrray" it sounds like there may be a 
 const-correctness issue with associative array itself rather 
 than this code? Before the move to 2.061 I had to cast away 
 const on const(V[K]) to get length and to iterate over them. 
 But why the link between History!double and RC[int] when they 
 are totally unrelated? Well, the only relation is their 
 aggregation in BSItem. Baffling.
The root of the problem is in: struct DAssociativeArray(Key, Value) { struct Slot { Value value; } } struct RC { this(this) { } } void main() { DAssociativeArray!(int, const(RC)) goo; } which doesn't compile (this is how Value[Key] is rewritten).
 Any suggestions appreciated.
 Thanks
 Dan
Feb 05 2013
parent reply "Dan" <dbdavidson yahoo.com> writes:
On Tuesday, 5 February 2013 at 15:06:47 UTC, Maxim Fomin wrote:
 The root of the problem is in:

 struct DAssociativeArray(Key, Value)
 {
     struct Slot
     {
         Value value;
     }
 }

 struct RC {
   this(this) {  }
 }

 void main()
 {
     DAssociativeArray!(int, const(RC)) goo;
 }

 which doesn't compile (this is how Value[Key] is rewritten).
I see - thanks. I assume it should compile and without the postblit it does. So - the original code is fine and there is a D problem with associative arrays. - Wouldn't the scenario be exactly the same without ValuationHistory? That is, if I comment out the member _valuationHistory, the goo member is not changed in structure at all, and yet it compiles just fine. - Does this mean that "no one" or "very few" developers store structs with postblits as value types in the standard associative array? Maybe I just do things differently than others. The way I see it you have to choose how you want to develop your structs/classes. I have chosen to use structs and templates and avoid classes, thinking this would greatly simplify things. Any struct needs to establish up front whether it will have value semantics or reference semantics. So far, I have preferred value semantics as data sharing leads to confusion. So if I have arrays in a struct I include postblits to provide value semantics. In another thread Walter made clear his distaste for postblits and preference for reference semantics coupled with copy on write semantics where needed. That approach, just does not seem worth it without more systematic support for COW. Assuming postblits are the issue, I don't understand why they are so hard to get right. Thanks Dan
Feb 05 2013
parent reply "Maxim Fomin" <maxim maxim-fomin.ru> writes:
On Tuesday, 5 February 2013 at 15:49:59 UTC, Dan wrote:
 - Wouldn't the scenario be exactly the same without 
 ValuationHistory? That is, if I comment out the member 
 _valuationHistory, the goo member is not changed in structure 
 at all, and yet it compiles just fine.
Scenario is the same if there is struct with postblit and const(S) is passed as AA argument. If there is more code involved, the situation can be more complicated.
 - Does this mean that "no one" or "very few" developers store 
 structs with postblits as value types in the standard 
 associative array? Maybe I just do things differently than 
 others.
This does not imply such situation, simply there is a problem. You can workaround by struct DAssociativeArray(Key, Value) { struct Slot { Value value; } } struct RC { int i; void postblit() { i = -5; } this(this) const { void delegate() dg = &postblit; dg(); } } void main() { RC rc1 = RC(5); RC rc2 = rc1; assert(rc2.i is -5); DAssociativeArray!(int, const(RC)) goo; }
Feb 05 2013
parent reply "Dan" <dbdavidson yahoo.com> writes:
On Tuesday, 5 February 2013 at 16:36:16 UTC, Maxim Fomin wrote:

 This does not imply such situation, simply there is a problem. 
 You can workaround by
[snip]
 struct RC {
     int i;
     void postblit() { i = -5; }
     this(this) const
     {
         void delegate() dg = &postblit;
         dg();
     }
 }
Great thanks. I'll try. But why does this even code work? I would have thought const guarantee would prevent calls to non-const postblit function. I was under impression this(this) const does not work - but maybe that has changed with 2.061. What source (lang spec, TDPL, or newsgroup) led you to this solution and for how long will it be valid? Where can I read more on it? Thanks Dan
Feb 05 2013
parent "Maxim Fomin" <maxim maxim-fomin.ru> writes:
On Tuesday, 5 February 2013 at 17:05:23 UTC, Dan wrote:
 But why does this even code work? I would have thought const 
 guarantee would prevent calls to non-const postblit function. I 
 was under impression this(this) const does not work - but maybe 
 that has changed with 2.061.
Forgot to mention, it works on 2.061.
 What source (lang spec, TDPL, or newsgroup) led you to this 
 solution and for how long will it be valid? Where can I read 
 more on it?

 Thanks
 Dan
Const postblit worked at least at 2.060. Originally idea was to make const cast on function call, but at a current time it is not needed. May be another bug.
Feb 05 2013
prev sibling parent "Maxim Fomin" <maxim maxim-fomin.ru> writes:
On Tuesday, 5 February 2013 at 01:15:28 UTC, Dan wrote:
 I've seen these type of errors often and usually the cause kind 
 of jumps out. In this case I'm totally confused. Just trying to 
 move from 2.06 to 2.061.

 The code is: http://dpaste.dzfl.pl/f40e4d6f
 and fails with the error in subject line. Observations:

 - If "static if(1)" is changed to "static if(0)" it compiles
 - If either _valuationHistory or goo member of BSItem is 
 commented out it compiles.

 I know the code is somewhat cryptic, but I've been using binary 
 reduction comment in/out to try to narrow down this issue. I 
 can not understand why an introduction of opEquals on a struct 
 History with no relationship to RC causes an error to show for 
 RC.

 Thanks
 Dan
There is still problem with const structs vs. non-const postblit and destructor. In the past, the situation was even worse, but was partly fixed by laxing constness with respect to postblit and destructor. Now all such problems seems to come from associative array implementation in object.d
Feb 05 2013