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