6 ms·
Today I learned that using const prevents the compiler from using move semantics. I am sad that I didn't already know this and also annoyed that C++ is so fiddl
by fancyfredbot 5y ago
Today I learned that using const prevents the compiler from using move semantics. I am sad that I didn't already know this and also annoyed that C++ is so fiddly. This is less obscure than the thread about std::launder on HN a few days ago but still counts as obscure for me, and you don't even get a friendly compiler warning when you do this. It just underlines for me the amount of knowledge required to truly become an expert on C++. It's such a powerful language but I sometimes wonder if all this complexity is a necessary consequence of that power.
- gpderetta 5y agoI would say this is pretty obvious. Moving form an object will leave it in a different state than it was before. Obviously it can't be done for const objects.
- Kranar 5y agoIt's not obvious at all, the issue is that move semantics in C++ don't really have much to do with the concept of moving. Most languages that have move semantics treat moves as a kind of relocation of a value from one place to another, hence the name. You're not changing the value, you're relocating it and in fact once the relocation is complete the original location is destroyed. So for example in Rust, you are absolutely welcome to move an immutable object. In C++, a move is an awkward kind of mutable copy operation with a special overloading rule that allows binding to rvalue references. There is nothing obvious about how it works, people get tripped up by it all the time along with all the additional complexity about when moves happen vs. when an elision happens vs. when a copy happens, the fact that T&& means wildly different things depending on whether T is a template parameter, and the bloated set of value categories introduced by it: glvalues, xvalues, rvalues, prvalues. I absolutely sympathize with anyone who doesn't feel like knowing all these C++isms.
- gpderetta 5y agoMost languages? I only know of two languages with move semantics: C++ and Rust. The latter has the benefit of a clean slate and build upon C++ experience. C++ had to be backward compatible with pre C++11 and couldn't make destructive moves work.
- Kranar 5y agoI did not say most languages, I said most languages that have move semantics. Neither C++ or Rust invented the concept which dates back to the 1980s. >C++ had to be backward compatible with pre C++11 and couldn't make destructive moves work. This is simply untrue as per the original proposal which left the door open to destructive moves (that door is now closed). There is nothing about destructive moves that make it incompatible with C++98/03. The main concern for destructive moves was how to deal with moves across an inheritance hierarchy, certainly a reasonable concern to have but nothing insurmountable by any means. The issue is that, as most things involving C++, decisions are pondered upon endlessly by a very small group of people not on the basis of their technical qualifications but on the basis of being able to to participate in the C++ standardization process, which requires physically travelling to numerous locations around the world at ones own expense. If C++ had a more open standardization process that embraced research from other languages and communities, this issue would have been solved. You can read the original proposal here: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2002/n1377.htm http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2002/n137... Note the section on destructive moves which doesn't mention anything to do with compatibility, and finally note why it wasn't adopted: "In the end, we simply gave up on this as too much pain for not enough gain." By "we" the author means three people gave up on it. Three people who couldn't find a solution to a problem (which has a solution) is why C++ is forever stuck without destructive move semantics.
- kaashif 5y ago> So for example in Rust, you are absolutely welcome to move an immutable object. In Rust, your code won't even compile if you try to use a moved-from value. In C++ what happens depends on what the moved-from state looks like. In C++, if you do something like use a moved-from value, it's really not obvious what "should" happen at all. It's not even obvious whether that should compile or be undefined behaviour. > I absolutely sympathize with anyone who doesn't feel like knowing all these C++isms. Any C++ programmer should agree with this. We don't want to know all of this bullshit and in fact would largely prefer if the compiler would know it for us...
- fancyfredbot 5y agoYou could equally say that destroying a const object changes its state, so you can't destroy const objects, but that would not be true! So I don't think this is exactly obvious, although I do like it as a way to explain the decision.
- gpderetta 5y agoBut destroying an object, by definition, does not leave an object around, so no state change can be observed. If you had destructive moves, then definitely moving from const objects could be a thing.
- Hokusai 5y ago> I sometimes wonder if all this complexity is a necessary consequence of that power. For many use cases you do not need all that knowledge. C++ is fast enough to not have to care. It's when you hit a wall that you need to get the extra tools to make things work. I have seen developers discussing obscure optimizations for a piece of code that will only be called once several minutes, and only after unparsing a JSON String. That one less instruction call by the CPU makes no difference whatsoever.
- bluGill 5y agoA large amount of knowledge is required to be a great programmer. The choices of what to learn are far more than anyone can learn in a lifetime. C++ gives a good abstraction for very low level operations, and has a great long term backward compatibility story. As such learning the details can be useful for anyone doing low level work over the long term. Rust is aiming at this space but doesn't have the long term track record (yet?). There are hundreds of other languages that you can also choose from with pros and cons. No matter what language you choose though, because low level details are important to you, you must learn fiddly low level bits to some extent as when move vs copy is used is by nature important. Of course part of this is about age. C++ goes back to the early 1970s (the C roots). In that time a lot of things have change. We have learned not to do things that seemed good. We have found better ways. The way hardware works has changed. What is important to speed has changed. Compilers now do optimizations. Whatever language you choose today will look dated in 50 years.