Hacker News new | ask | show | jobs
by saurik 4665 days ago
The argument here is that in the body of the constructor the developer probably doesn't use s, so a trivial analysis of the function can say "oh, it doesn't matter if I destroy s, so in the one place where it is used I'll just move it". It doesn't then matter if it is obvious it happens or not, because the semantics of the program wouldn't be maintained (and honestly, I'd argue it is never quite obvious when what happens in different contexts given the large number of rules involved: you kind of just have to have some trust).
1 comments

There are a number of considerations because the compiler can't prove it in general without augmenting the type system or doing whole-program analysis.

Do you allow, but not require, the compiler to do this substitution whenever it can prove a value is never used again? This is unreliable across build options and compilers so it would be unwise to depend on it. There is an opportunity here for a tool that could identify places where you could insert move, perhaps even a -W option for the trivial cases such as above, but I am not convinced the language should allow the compiler to do this.

Do you make it mandatory and add more special cases for the compiler to have to implement? This would require the compiler to track references to make sure they don't get passed to some other function. It would need someone to codify the special cases in the standard and this might be very difficult. It would also be fragile, there would be cases where implicit move used to kick in but some added function call inhibits it even though a move is still the right thing to do.

You seem to be assuming that optimizations are only of value if they can be depended on happening consistently as a defined property of the language on every single platform for which there exists a compiler: in practice, compilers perform numerous optimizations (such as static branch prediction) that only work probabilistically even for the case of a specific version of a specific compiler on a specific operating system; I know of very few people (maybe you are one of them, however) who consider this to be a detriment. For a more obvious comparison: yes, I could sit around constructing object pools in my Java program to avoid heap allocations and their associated garbage collection penalty, but if rudimentary escape analysis manages to pick up a lot of the value, even if "fragile" or nondeterministic, I might not need to spend the time anymore to worry about that kind of detail in my software as the cost benefit analysis shows that the toolchain is now a more efficient usage of resources towards that issue (I could be spending my energy working on algorithm design, for example, instead of object pools). As long as the semantics of the language support the optimization, and as it doesn't seem to be difficult to implement, it would be useful to have the compiler perform this optimization for the developer, and one would expect such an optimization to either already be there or be "in the works".
This is a very different kind of optimization than the other things you are talking about. This is something that is operating at a high level and potentially has implications that might not be obvious. You are changing the type of something and effecting the function overloads which are resolved. I think its important for what functions you are calling to be deterministic. My previous post was just touching on what possible value can be gained from allowing this and my conclusion is that it would be very little.

Also, your example of escape analysis is precisely because Java doesn't allow you to express what you are wanting to do, whereas C++ does allow you to express moves.

edit: I would compare this to C++'s copy elision, but that has a very high value and is much less intrusive.

I guess considering a user defined move constructor could do something arbitrarily stupid you have to be consistent.
Also, any function can be overloaded on rvalue references.