Possible optimization opportunity when assigning to a member in the constructor

deadalnix deadalnix at gmail.com
Thu Mar 14 21:54:19 PDT 2013


On Friday, 15 March 2013 at 04:09:25 UTC, Ali Çehreli wrote:
> struct Inner below has an opAssign that gets called in 
> Outer.this even with -O. That opAssign call seems unnecessary:
>
> import std.stdio;
>
> struct Inner
> {
>     int i;
>
>     void opAssign(Inner rhs)
>     {
>         writeln("moving");
>     }
> }
>
> struct Outer
> {
>     Inner inner;
>
>     this(int i)
>     {
>         writeln("Assigning to this.inner");
>         this.inner = Inner(i);
>     }
> }
>
> void main()
> {
>     writeln("Constructing main.inner");
>     auto inner = Inner(42);
>
>     writeln("Constructing main.outer");
>     auto outer = Outer(43);
> }
>
> The two lines in main are different from the point of view of 
> two Inners in the program: The first one is the construction of 
> an Inner variable. The second one is the construction of an 
> Outer variable which happens to have an Inner member.
>
> Here is the output of the program:
>
>   Constructing main.inner
>   Constructing main.outer
>   Assigning to this.inner
>   moving
>
> I think the last line should not happen.
>
> Naturally, there is no opAssign called when constructing 
> main.inner. However, the assignment to this.inner in the 
> constructor is treated as a "move" of the value Inner(i) on top 
> of the value of Inner.init. Although there is nothing wrong 
> with that, I think the compiler can simply blit Inner(i) to 
> this.inner and doing so would be safe.
>
> Does that make sense? Something like "If an rvalue is assigned 
> to a member in a constructor, do not call opAssign() of the 
> member".
>
> Ali

Yes, in general, first assignment in a constructor should be 
considered as a declaration if the value is not read before.

This allow for the mentioned optimization, but many very other 
important stuff as well, like the construction of immutable 
objects.


More information about the Digitalmars-d mailing list