fieldPostBlit - what is wrong with this and workarounds
Jonathan M Davis
jmdavisProg at gmx.com
Thu Oct 31 12:39:33 PDT 2013
On Thursday, October 31, 2013 15:03:26 Daniel Davidson wrote:
> Given this code:
>
> import plus.tvm.rate_curve;
> struct T {
> RateCurve m;
> }
> struct S {
> const(T) rc;
> }
>
> I get this error: Error: mutable method
> plus.models.dossier.__unittestL42_1.T.__fieldPostBlit is not
> callable using a const object
>
> Is this fundamentally incorrect? I abandoned immutable in hopes
> that const would be more manageable and so far it has. But these
> types of issues still crop up and stop me in my tracks.
>
> What are the requirements on RateCurve and T for this to work?
const and postblit fundamentally don't mix, because for it to work, you have
to violate the type system. With postblits, the struct gets memcpied and then
the postblit constructor has the chance to mutate the resulting object to make
the pieces different that need to be different. However, to do that mutation
when the object is const would mean mutating a const object which violates the
type system. What we really need is copy constructors, but they haven't been
added yet. At one point, Andrei was saying that he and Walter had a solution,
but he didn't elaborate on it. I assume that it involved introducing copy
constructors, but I don't know, and this issue has not yet been resolved.
Now, in your particular code example, you don't define postblit constructor,
but my guess would be that RateCurve defines one, making it so that a postblit
constructor is generated for T which uses the one for RateCurve, and the S
gets one which uses T's. And because const doesn't work with postblit
constructors, S becomes uncopyable, and if there's any code that requires that
a copy be made, then it'll fail to compile (I'm not sure whether the fact that
it's uncopyable will result in an error if no attempts to copy it are made,
but you'll definitely get an error if an attempt to copy is made).
Hopefully, this problem will be resolved, but regardless of that, I would
advise against ever having a const member variable in a struct. Even if you
don't have any postblit issues, such a struct can never be assigned to, and it
becomes essentially unusuable in any situation where you would have to assign
a value to it (e.g. if it were in an array). You can certainly make a struct's
member variable const if you want to, but you're going to run into stuff that
won't work as a result. It's far better to just provide a property for it
which is const (probably returning the member by const ref if you want to
avoid copying it when using the property) rather than making the member
variable itself const.
- Jonathan M Davis
More information about the Digitalmars-d-learn
mailing list