Jump to page: 1 2
Thread overview
x.RC.__postblit () is not callable using argument types () const
Feb 05, 2013
Dan
Feb 05, 2013
Ali Çehreli
Feb 05, 2013
Dan
Feb 05, 2013
Andrej Mitrovic
Feb 05, 2013
Maxim Fomin
Feb 05, 2013
Dan
Feb 05, 2013
Maxim Fomin
Feb 05, 2013
Dan
Feb 05, 2013
Maxim Fomin
Feb 05, 2013
Dan
Feb 05, 2013
Maxim Fomin
Feb 05, 2013
Maxim Fomin
February 05, 2013
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
February 05, 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
> 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
February 05, 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

February 05, 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.
February 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
> 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
February 05, 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.
February 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:
>> 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
February 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

February 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

February 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;
}

« First   ‹ Prev
1 2