Copying structs with pointers

Jonathan M Davis jmdavisProg at gmx.com
Wed Jul 20 15:50:26 PDT 2011


On 2011-07-20 15:30, Peter Alexander wrote:
> On 20/07/11 11:06 PM, Jonathan M Davis wrote:
> > Postblit doesn't work with const or immutable right now:
> > http://d.puremagic.com/issues/show_bug.cgi?id=4867
> 
> Is that the issue though? I believe it's a deeper issue.

It means that regardless of whether there's a deeper issue, using const with 
postblit isn't going to work.

> An example:
> 
> struct Ptr
> {
> int* p;
> this(int x) { p = new int; *p = x; }
> this(this) { /+ do nothing +/ } // (!!!)
> const int get() { return *p; }
> void set(int x) { *p = x; }
> }
> 
> void main()
> {
> const Ptr a = Ptr(1);
> Ptr b = a; // shallow copy! const removed!
> b.set(2);
> assert(a.get() == 1); // FAIL
> }
> 
> 
> If you allow this then it means that you can get a non-const pointer
> through a const object, which breaks the transitivity of const.

Hmmm. This is definitely a problem. It should be possible to use postblits 
when the object being copied is const and has pointers and/or references. If 
not, that's fairly crippling. But without doing some sort of flow analysis, I 
don't see how the problem that you present can be fixed. If it were a copy 
constructor, it would be straightforward - everything gets default initialized 
and then you assign stuff from the const original, making copies where 
required. But a postblit does a shallow copy _first_, which means that either 
this is forced to point to const (thereby making it so that you can't do 
anything but a shallow copy and that the copy must be const), or the type 
system gets twisted a bit by allowing this to point to mutable even though 
it's const and the compiler then must ensure that copies are made (or at least 
that the original values are not kept) or const would be bypassed (and even 
that probably wouldn't work, since then you'd have to worry about the member 
variables being passed to functions as mutable inside of the constructor when 
they're really const underneath). And I don't think that either of those 
solutions really works.

Maybe we actually need a copy constructor of some kind for this sort of case. 
I don't see how to get around it with a postblit. This is definitely a big 
problem.

- Jonathan M Davis


More information about the Digitalmars-d mailing list