Confused about const

Paul D. Anderson paul.d.removethis at comcast.andthis.net
Fri Mar 19 20:06:55 PDT 2010


bearophile Wrote:

> Paul D. Anderson:
> > My struct has a dynamic array as a member -- that seems to be the problem. This code doesn't compile:
> > 
> > struct S {
> >  int x;
> >  int[] a;
> > }
> > 
> > S foo(const S b) {
> >     S other = b;
> >     return other;
> > }
> > void main() {}
> 
> This compiles, oh joy:
> 
> struct S {
>     int x;
>     int[] a;
> }
> S foo(const S b) {
>     S other;
>     other.x = b.x;
>     other.a = b.a.dup; // the dup is necessary here
>     return other;
> }
> void main() {}
> 
> 
> The idea now is to find a way to encapsulate that manual copying & dupping into some overloaded operator of S. But I have failed so far. Operator overloading in D2 is not an easy thing, it needs training. (That's why I have recently asked for the compiler to be strict to avoid wrong usages of the operator overloading.)
> 
> Bye,
> bearophile

Yes, thanks to you and biozic for finding the root of the problem. Here's a piece of code that demonstrates the problem:

//-------------

struct S {
int x;
int[] a;

// including this postblit causes an error because the default
// constructor it applies to doesn't allow const argument.

/+this(this) {
	a = a.dup;
}+/

// adding a const to the argument of this constructor allows case 2.
this(const S s) {
	x = s.x;
	a = s.a.dup;
}

// including or excluding this constructor doesn't change
// the compilability.
/+this( S s) {
	x = s.x;
	a = s.a.dup;
}+/

// an opAssign with a const argument allows case 3.
S opAssign(const S s) {
	this.x = s.x;
	this.a = s.a.dup;
	return this;
}
	
// including this doesn't make a difference.
// I think this is the same as the default opAssign.
/+S opAssign(S s) {
	this.x = s.x;
	this.a = s.a.dup;
	return this;
}+/
	
}

// case 1: no const. According to the spec this is 
// a copy constructor in action.
S foo(S b) {
    S other = b;
    return other;
}

// case 2: const, but assignment requires the creation of a
// non-const S from before assignment.
S bar(const S b) {
    S other = S(b);
    return other;
}

// case 3: const, but creation and assignment are separate.
// this is a default construction and opAssign(const).
S foo(const S b) {
    S other;
	other = b;
    return other;
}

// case 4:const. According to the spec this is
// a copy constructor in action, but it goes awry.
// does not compile.
S foo(const S b) {
    S other = b;
    return other;
}

void main() {}

/----------------------

So I understand better now, thanks, what is wrong. I'm a little disappointed that there is apparently no way to implement case 4 for any struct with a reference.

Paul

p.s. Does it make any sense to send this over to the D forum to get more eyes on the problem?




More information about the Digitalmars-d-learn mailing list