Inability to dup/~ for const arrays of class objects

Steven Schveighoffer schveiguy at yahoo.com
Tue May 28 17:37:12 PDT 2013


On Tue, 28 May 2013 20:08:44 -0400, Ali Çehreli <acehreli at yahoo.com> wrote:

> On 05/28/2013 04:32 PM, Peter Williams wrote:
>
>  > I find that dup works for const T[] when T is not a class (although I
>  > haven't tried it with pointers).  This means I write two versions of  
> my
>  > code - one for classes (which does (cast(T[])).dup) and one for the  
> rest.
>
> There is current and related thread on the D.learn forum:
>
>    http://forum.dlang.org/post/bsbhpdgcpfmkvsclsskq@forum.dlang.org
>
> I think it is unnecessarily restrictive that a const class variable  
> cannot refer to another class object:
>
> class C
> {}
>
> void main()
> {
>      const(C) c;
>      c = new const(C);    // <-- compilation error
> }

This is a separate problem.  What you are looking for could be legal if  
syntax existed for it.

dup-ing just copies the class reference.  It does not copy the bits.

For example:

class C
{
    pure this(int _x) {x = _x;}
    int x;
}

immutable(C) c = new immutable(C)(5);

const(C)[] arr;
arr ~= c;
auto mc = (cast(C[])arr).dup; // error without cast!
mc[0].x = 6;
assert(c.x == 6); // oops!  changed immutable

> I think this limitation is at the core of your issue as well: .dup  
> creates mutable objects but your array is not able to contain const  
> class variables to refer to those mutable objects. I think it should be  
> possible.

This is a different problem.  Your problem is you can't apply const  
selectively to the tail of the reference.  It's fundamentally sound, but D  
lacks the syntax to do it.

Peter's problem is that you can't implicitly cast an indirection away from  
const, which is a fundamentally unsound operation.

> I have a feeling that this may be related to that surprising issue with  
> C and C++:
>
>    http://www.parashift.com/c++-faq-lite/constptrptr-conversion.html
>
> The reason I suspect so is because a class variable is one level of  
> indirection and a slice is another level of indirection. Does that make  
> this issue the same as the C++ issue? If not, perhaps the implementation  
> of such a limitation is the cause of this bug. (?)

This is a different problem also, but also is disallowed for good reason.

The equivalent in D slices would be this:

int*[] arrofintptrs = new int*[1];
const(int)*[] arr2 = arrofintptrs; // error....
const int i = 5;
arr2[0] = &i; // ...because of this
*arrofintptrs[0] = 6; // oops, changed i!

-Steve


More information about the Digitalmars-d mailing list