digitalmars.D.learn - x.RC.__postblit () is not callable using argument types () const
- Dan (14/14) Feb 04 2013 I've seen these type of errors often and usually the cause kind
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (24/38) Feb 04 2013 Further reduced:
- Dan (12/16) Feb 04 2013 Thanks Ali. If const is removed it will compile.
- Andrej Mitrovic (5/6) Feb 04 2013 The error in the git-head version is:
- Maxim Fomin (3/5) Feb 05 2013 This is sub struct inside object.AssociativeArray.
- Dan (35/40) Feb 05 2013 Is it the case that this is a D compiler (or library) problem and
- Maxim Fomin (18/35) Feb 05 2013 The root of the problem is in:
- Dan (26/42) Feb 05 2013 I see - thanks. I assume it should compile and without the
- Maxim Fomin (29/37) Feb 05 2013 Scenario is the same if there is struct with postblit and
- Dan (12/23) Feb 05 2013 Great thanks. I'll try.
- Maxim Fomin (5/14) Feb 05 2013 Const postblit worked at least at 2.060. Originally idea was to
- Maxim Fomin (6/21) Feb 05 2013 There is still problem with const structs vs. non-const postblit
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
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 DanFurther 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
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
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
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
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: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 DanYeah, 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
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
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
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
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
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 DanConst 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
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 DanThere 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