Re: C# very optimisation



James Curran wrote:


    You'll note that this is the pre-fix operator++.  So, where is the
post-fix?  The C# compiler creates it for you automatically.  And is it
written?  Basically:

    public static MyClass operator++(MyClass a) // post-fix
    {
            MyClass b = a.Clone();
            ++a;
            return b;
    }

No, From the help-files:

The run-time processing of a postfix increment or decrement operation of the form x++ or x-- consists of the following steps:

If x is classified as a variable:
x is evaluated to produce the variable.
The value of x is saved.
The selected operator is invoked with the saved value of x as its argument.
The value returned by the operator is stored in the location given by the evaluation of x.
The saved value of x becomes the result of the operation.



Which means that the post-operator++ will only work "as expected" if x is a struct. Try the example program below.


    So, like in the C++,  the post-fix has to create a copy of the unaltered
object, so that it can be returned.

If the type is a struct, otherwise a *wrong* (or unhelpfull, at least) post-operator++ is generated. for C# a struct-return is always a bit-by-bit copy, so no copy-constructor can be run here, the old struct is simply copied bit-by bit and has the operator++ applied to it.


    When an int is used, the operator method is inlined, so, when it's just
"x++;" on a line by itself, the compile can see that the duped value isn't
used, and it can remove the whole creation of it.  When ++ is used on some
other type object, the oper++ is done out-of-line, and so, the compiler
cannot remove it.

Have you disassembled the code to verify that the optimizer does this? (on structs... of course it won't on classes).


===> test program <===
using System;
class C
{
  int i;
  public static C operator++(C c) { c.i += 1; return c; }
  public override string ToString() { return i.ToString(); }
}
struct S
{
  int i;
  public static S operator++(S s) { s.i += 1; return s; }
  public override string ToString() { return i.ToString (); }
}
class Test
{
  public static void print(string prefix, C c)
  { Console.WriteLine("{0}: {1}, id={2}", prefix, c, c.GetHashCode()); }
  public static void print(string prefix, S s)
  { Console.WriteLine("{0}: {1}, id={2}", prefix, s, s.GetHashCode()); }

  public static void Main()
  {
    S s = new S();
    print("s", s);
    print("++s", ++s);
    print("s", s);
    print("s++", s++);
    print("s", s);

    C c = new C();
    print("c", c);
    print("++c", ++c);
    print("c", c);
    print("c++", c++);
    print("c", c);
  }
}
===> output <===
s: 0, id=0
++s: 1, id=1
s: 1, id=1
s++: 1, id=1
s: 2, id=2
c: 0, id=1
++c: 1, id=1
c: 1, id=1
c++: 2, id=1
c: 2, id=1


-- Helge Jensen mailto:helge.jensen@xxxxxxx sip:helge.jensen@xxxxxxx -=> Sebastian cover-music: http://ungdomshus.nu <=- .