C++ and zombies: a moving question(meetingcpp.com)
meetingcpp.com
C++ and zombies: a moving question
http://meetingcpp.com/index.php/br/items/cpp-and-zombies-a-moving-question.html
6 comments
I got into C++ back in 1993, and it has been one of the main languages on my toolbox. So I do like it quite much.
But I am also spoiled by Niklaus Wirth legacy in language design and safe systems programming. As well as ML languages.
C++14 feels quite modern, and I enjoy playing with it on hobby projects where I have full control, but I don't miss those C++98 enterprise code bases.
But I am also spoiled by Niklaus Wirth legacy in language design and safe systems programming. As well as ML languages.
C++14 feels quite modern, and I enjoy playing with it on hobby projects where I have full control, but I don't miss those C++98 enterprise code bases.
The biggest problem with destructive move in C++ (and one I personally think is unfixable, but I'm happy to be proved wrong), is that in most cases algorithms must be sure to recreate any variable they are not responsible for, as it will be destroyed later. There isn't any way of checking if some memory has already been destroyed, and adding any kind of flag just gets us back to the same position really. In particular I tried writing an exception safe std::sort (so make sure when std::sort exits all variables are reconsructed again), and it is an extremely difficult undertaking.
In general I find the lack of destructive move isn't a serious problem -- designing variables so their 'default state' is very cheap to construct isn't usually a major cost.
In general I find the lack of destructive move isn't a serious problem -- designing variables so their 'default state' is very cheap to construct isn't usually a major cost.
I think it was Dave Abrahams who first brought up the issue of destructors with side effects and their implications for move semantics. For example, a destructor may have the side effect of releasing a lock. If I remember correctly, Dave's advice was to write your move operations in such a way that they always perform at least those destructor actions that have side effects. I seem to remember that he discussed this on his cpp-next blog, but the site appears to be down. Does anybody know if those blog posts are available somewhere?
cpp-next seems to be lost, at least for the web, but you still can access its content at the webarchive.org.
Consider a Movable file handle.
File fh = File(fopen("file.txt"));
foo(std::move(fh));
Using fh after foo() would yield a compile error in Rust. It does not in C++.
File fh = File(fopen("file.txt"));
foo(std::move(fh));
Using fh after foo() would yield a compile error in Rust. It does not in C++.
Well, of course accessing the value of fh after foo would be fatal.
But how would you then sort a container of moveable-only objects?
An object should be accessible for reassigning a value after its move, as its often needed for algorithms, thats exactly why the C++ Standard mandates this. Move does really only make sense if the class holds a moveable allocation, such as a container, array etc., which makes copying expensive.
An object should be accessible for reassigning a value after its move, as its often needed for algorithms, thats exactly why the C++ Standard mandates this. Move does really only make sense if the class holds a moveable allocation, such as a container, array etc., which makes copying expensive.
> An object should be accessible for reassigning a value after its move, as its often needed for algorithms, thats exactly why the C++ Standard mandates this.
The same is true in Rust. A moved-from value can be reassigned, but cannot be used (compile enforced) until it is reassigned. :)
The same is true in Rust. A moved-from value can be reassigned, but cannot be used (compile enforced) until it is reassigned. :)
How often do people make this error? I know, it's a terrible error but I code every day (maybe my opinion is not relevant for this reason) and I rarely come across this issue.
How big is your team?
I'm sincerely asking since I work alone.
Big projects are often composed anywhere from 10 developers up to 100 or more.
Usually with high rotation of developers coming and going, since parts of the project tend to be delegated to be other companies, many times with developers that aren't all at the same skill level.
When you work at this scale, memory errors and misuse of resource are quite common.
No developer is able to have the whole code on his/her head and sometimes also does not have the time to understand the whole codebase.
So mistakes happen quite often.
This is why C got out of love in the enterprise or why companies like Google and JPL have such strict C++ design guide.
Usually with high rotation of developers coming and going, since parts of the project tend to be delegated to be other companies, many times with developers that aren't all at the same skill level.
When you work at this scale, memory errors and misuse of resource are quite common.
No developer is able to have the whole code on his/her head and sometimes also does not have the time to understand the whole codebase.
So mistakes happen quite often.
This is why C got out of love in the enterprise or why companies like Google and JPL have such strict C++ design guide.
I feel like a complete idiot when I read these articles :-( I can hardly even understand the issues because c++ have gotten to a point where I have to strain myself very hard to even understand the problem (forget the solution). And I have been programming with c++ for many years (but c++11 ignorant).
Well, stay away from r-value references[1], and trust the defaults for move will make your live a lot easier.
To Quote Eric Niebler: "I want you to fear r-value references, like one could fear god" (last year at Meeting C++)
[1]except things like forwarding in templates, but thats fairly easy.
To Quote Eric Niebler: "I want you to fear r-value references, like one could fear god" (last year at Meeting C++)
[1]except things like forwarding in templates, but thats fairly easy.
No, this is just the destructive move problem for single ownership pointers. It's an use case for "swap" as a language primitive.
The real problem is that you just can't make single-ownership pointers work right in C++ via the template mechanism. I tried a few times, over a decade ago. (http://animats.com/papers/languages/index.html) It takes a more global look than you have down inside a template. You need language-level support.
Rust does this. It's not inherently hard. It's just extremely hard to retrofit to the C++ model. Look at the history of auto_ptr, and now unique_ptr in C++. The pain. The anguish. The decades of headaches. The unnecessary complexity. The pain.