digitalmars.D.learn - Problem overloading operator for a struct with an immutable member
- Nicolas Sicard (19/19) Mar 24 2015 I don't know if this is a bug or expected behaviour. The struct
- ketmar (9/29) Mar 25 2015 yes, this is a bug. it happens due to compiler rewrite rule (postfix=20
- ketmar (3/24) Mar 25 2015 by the way. do you know that you still CAN overload postincrement=20
- Jean pierre (18/47) Mar 25 2015 There's might be a bug anyway because even with an alias this:
- ketmar (7/8) Mar 25 2015 but why one expecting `i` here? there IS `opUnary` overload, and `++`=20
- Nicolas Sicard (21/25) Mar 26 2015 Thnaks. Indeed, this works:
I don't know if this is a bug or expected behaviour. The struct is mutable, assignable and pre-increment operator works. But post-increment doesn't compile because of the immutable member. -- struct S { int i; immutable(Object) o; S opUnary(string op)() { return this; } void opAssign(S other) {} } void main() { S s, t; t = s; // OK ++s; // OK s++; // Error: cannot modify struct s S with immutable members } ---
Mar 24 2015
On Tue, 24 Mar 2015 16:49:01 +0000, Nicolas Sicard wrote:I don't know if this is a bug or expected behaviour. The struct is mutable, assignable and pre-increment operator works. But post-increment doesn't compile because of the immutable member. =20 -- struct S { int i; immutable(Object) o; =20 S opUnary(string op)() { return this; } void opAssign(S other) {} } =20 void main() { S s, t; =20 t =3D s; // OK ++s; // OK s++; // Error: cannot modify struct s S with immutable members }yes, this is a bug. it happens due to compiler rewrite rule (postfix=20 operation is rewritten to expression like 'auto tmp =3D var; ++var; tmp',=20 but before this compiler tries to check if `var` is modifiable lvalue. i.e. for prefix increment compiler FIRST checks for operator overload,=20 and only THEN checks for modifiable lvalue (if there is no overload). but for postfix increment compiler FIRST checks for modifiable lvalue,=20 and only THEN tries to rewrite expression and find operator overload. =
Mar 25 2015
On Tue, 24 Mar 2015 16:49:01 +0000, Nicolas Sicard wrote:I don't know if this is a bug or expected behaviour. The struct is mutable, assignable and pre-increment operator works. But post-increment doesn't compile because of the immutable member. =20 -- struct S { int i; immutable(Object) o; =20 S opUnary(string op)() { return this; } void opAssign(S other) {} } =20 void main() { S s, t; =20 t =3D s; // OK ++s; // OK s++; // Error: cannot modify struct s S with immutable members } ---by the way. do you know that you still CAN overload postincrement=20 operation? yes, the code is still here, and it works... somethimes. ;-)=
Mar 25 2015
On Thursday, 26 March 2015 at 04:57:55 UTC, ketmar wrote:On Tue, 24 Mar 2015 16:49:01 +0000, Nicolas Sicard wrote:There's might be a bug anyway because even with an alias this: --- struct S { int i; alias i this; immutable(Object) o; S opUnary(string op)() { return this; } void opAssign(S other) {} } void main() { S s, t; auto j = s.i++; // OK auto i = s++; // OUCH, but we expect S.i... } ---I don't know if this is a bug or expected behaviour. The struct is mutable, assignable and pre-increment operator works. But post-increment doesn't compile because of the immutable member. -- struct S { int i; immutable(Object) o; S opUnary(string op)() { return this; } void opAssign(S other) {} } void main() { S s, t; t = s; // OK ++s; // OK s++; // Error: cannot modify struct s S with immutable members } ---by the way. do you know that you still CAN overload postincrement operation? yes, the code is still here, and it works... somethimes. ;-)
Mar 25 2015
On Thu, 26 Mar 2015 05:44:13 +0000, Jean pierre wrote:auto i =3D s++; // OUCH, but we expect S.i...but why one expecting `i` here? there IS `opUnary` overload, and `++`=20 corretly transformed to prefix form. there is simply NO postfix form in=20 semantically analyzed code, *all* postfix increments and decrements are=20 transformed. or, to say it another way, D has no postfix inc/dec operator, there are=20 only prefix forms. postfix form it just a compiler syntactic sugar.=
Mar 25 2015
On Thursday, 26 March 2015 at 04:57:55 UTC, ketmar wrote:by the way. do you know that you still CAN overload postincrement operation? yes, the code is still here, and it works... somethimes. ;-)Thnaks. Indeed, this works: --- struct S { int i; immutable(Object) o; void opAddAssign(int j) { i += j; } S opPostInc() { ++i; return this; } void opAssign(S other) {} } unittest { S s; ++s; assert(s.i == 1); s++; assert(s.i == 2); } --- Old operator overloading to the rescue !
Mar 26 2015
On Thu, 26 Mar 2015 09:02:53 +0000, Nicolas Sicard wrote:On Thursday, 26 March 2015 at 04:57:55 UTC, ketmar wrote:just make sure you didn't add `opUnary` there, as it will kill=20 `opPostInc`. it worth nothing that `opPostInc` is not deprecated yet. ;-)=by the way. do you know that you still CAN overload postincrement operation? yes, the code is still here, and it works... somethimes. ;-)=20 Thnaks. Indeed, this works: --- struct S { int i; immutable(Object) o; =20 void opAddAssign(int j) { i +=3D j; } S opPostInc() { ++i; return this; } void opAssign(S other) {} } =20 unittest { S s; ++s; assert(s.i =3D=3D 1); s++; assert(s.i =3D=3D 2); } --- =20 Old operator overloading to the rescue !
Mar 26 2015
On Thu, 26 Mar 2015 09:17:21 +0000, ketmar wrote:worth nothingheh. my pet misspelling. =
Mar 26 2015