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