5 ms·
As somebody who attended this conference, and hadn't had much exposure to C++11 features outside of 'auto', my personal biggest takeaway from almost every talk
by zowch 13y ago
As somebody who attended this conference, and hadn't had much exposure to C++11 features outside of 'auto', my personal biggest takeaway from almost every talk was this: Stop passing your sink variables as const refs.
That is to say if you have a constructor:
MyClass::MyClass(const std::string& s) : m_s(s) {}
That you call like:
std::string s = "Some string";
MyClass c(s);
You're hamstringing the compiler into always copying that string instead of being able to use the new move semantics, because it can't mess with the guts of a const reference. Instead, do the previously unspeakable evil of passing by value and then moving, e.g.
MyClass::MyClass(std::string s) : m_s(std::move(s)) {}
This lets the compiler know that if string has a move constructor, and is an rvalue, it can just move the guts into place instead of performing the copy, since the variable is 'sunk' into the new location. Huge wins all around.
- a8da6b0c91d 13y agoIs the std::move call really necessary? It's a little sad if the compiler can't see that s is already an rvalue.
- plorkyeran 13y agos isn't an rvalue. It has a name, and you can refer to it within the body of the constructor.
- a8da6b0c91d 13y agoI understand that, but it's clearly not used in the body. I was hoping it would be a legal and implemented optimization. move calls strike me as ugly and kinda dangerous. What if you do wind up wanting to refer to s in the body later on? It'd be nice if the compiler just handled it.
- marshray 13y ago> What if you do wind up wanting to refer to s in the body later on? Then copy s, don't move it.
- a8da6b0c91d 13y agoThe point is move makes things that look like values as annoying as pointers. You have to keep track.
- marshray 13y agoI'll buy that.
- detrino 13y agoOnce things have a name and you can take their address they are no longer an rvalue. It would require a much more sophisticated type system to do this automatically (when you pass a reference to another function, does it capture it?). It would also be non-obvious when you were moving. Think of Java style escape analysis vs C++ stack allocation (implicit vs explicit). There is one case where the compiler will do this though, when you return a stack allocated value from a function, it is implicitly moved.
- saurik 13y agoThe 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).
- detrino 13y agoThere 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.
- 13y ago