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