www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Problem overloading operator for a struct with an immutable member

reply "Nicolas Sicard" <dransic gmail.com> writes:
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
next sibling parent ketmar <ketmar ketmar.no-ip.org> writes:
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
prev sibling parent reply ketmar <ketmar ketmar.no-ip.org> writes:
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
next sibling parent reply "Jean pierre" <vazyjeanpierre nowhere.uk> writes:
On Thursday, 26 March 2015 at 04:57:55 UTC, ketmar wrote:
 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.
 
 --
 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. ;-)
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... } ---
Mar 25 2015
parent ketmar <ketmar ketmar.no-ip.org> writes:
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
prev sibling parent reply "Nicolas Sicard" <dransic gmail.com> writes:
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
parent reply ketmar <ketmar ketmar.no-ip.org> writes:
On Thu, 26 Mar 2015 09:02:53 +0000, Nicolas Sicard wrote:

 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. ;-)
=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 !
just make sure you didn't add `opUnary` there, as it will kill=20 `opPostInc`. it worth nothing that `opPostInc` is not deprecated yet. ;-)=
Mar 26 2015
parent ketmar <ketmar ketmar.no-ip.org> writes:
On Thu, 26 Mar 2015 09:17:21 +0000, ketmar wrote:

 worth nothing
heh. my pet misspelling. =
Mar 26 2015