![]() |
|
[rant] C++0x is ...so simple. |
anonymous
Member #8025
November 2006
|
But rvalue references and auto_ptr are still a completely different thing? (The former is even a way to fix the latter: provide a really simple smart pointer that you can store safely in standard containers etc.) The compiler will implicitly move only in places where you can't miss the original (those rules have been in place for a long time, e.g where copy constructor calls can be elided), and in addition rvalue references provide a sure way to determine cases where it is always safe to move explicitly. In addition there are a few specific cases where moving is OK due to the nature of the algorithm (swap, when resizing vector etc). #include <vector> #include <memory> using namespace std; int main() { vector<unique_ptr<int>> v; unique_ptr<int> p (new int); v.push_back(p); //compiler error: unique_ptr is non-copyable v.push_back(unique_ptr<int>(new int)); //OK, and you can't miss this unique_ptr }
|
axilmar
Member #1,204
April 2001
|
anonymous said: The compiler will implicitly move only in places where you can't miss the original. You said that 3 times. Ok, I understood it, I agree with you. The problem is not that. The problem is how this is going to be used by the programmers. A programmer may explicitly move things around only to mess things up later. Trying to find where data are moved in code is extremely difficult, especially if the code is complex. How about: #include <vector> #include <memory> using namespace std; int main() { vector<unique_ptr<int>> v; unique_ptr<int> p (new int); v.push_back(p); //compiler error: unique_ptr is non-copyable v.push_back(foo(unique_ptr<int>(new int))); //not OK; foo may keep a pointer to the data. }
|
anonymous
Member #8025
November 2006
|
And you have mentioned this a couple of times as well. Provide a real example of what foo would have to look like without a dumb use of std::move and then keeping using the same variable. Yes, given a large and messy codebase written by people that come and go, I can imagine that any line can contain any arbitrary hidden bug. Misuse of std::move seems to be on the benign end of things that could go wrong. What I'm saying that rvalue references seem to protect you quite nicely from honest human errors, but not from incompetence, and are therefore much easier and safer to use than many other existing features. |
axilmar
Member #1,204
April 2001
|
anonymous said: And you have mentioned this a couple of times as well. Provide a real example of what foo would have to look like without a dumb use of std::move and then keeping using the same variable. Yes, given a large and messy codebase written by people that come and go, I can imagine that any line can contain any arbitrary hidden bug. Misuse of std::move seems to be on the benign end of things that could go wrong. What I'm saying that rvalue references seem to protect you quite nicely from honest human errors, but not from incompetence, and are therefore much easier and safer to use than many other existing features. I agree with you, except for the "misuse of std::move seems be on the benign end of things". Accessing memory previously deleted is one of the most difficult bugs to solve. |
anonymous
Member #8025
November 2006
|
axilmar said: I agree with you, except for the "misuse of std::move seems be on the benign end of things". Accessing memory previously deleted is one of the most difficult bugs to solve. But when an object has been moved from, it is not deleted memory in the same sense as what you get when you type delete p;. That object has to be in a good enough state, so at least its destructor can still run (e.g it contains NULL pointers, or I suppose it might have swapped the pointers). Unlike misusing delete, where the language itself cannot check that you follow a sensible ownership policy, with rvalue references you have a good idea where std::move cannot hurt. The only thing to keep in mind is not to keep using the moved-from object, unless you put it in a good state again (mostly you'd move from things that are going out of scope anyway). #include <cstdio> #include <memory> int main() { std::unique_ptr<int> a(new int(10)); std::unique_ptr<int> b(std::move(a)); a.reset(new int(20)); //this should be OK printf("%d %d\n", *a, *b); }
|
X-G
Member #856
December 2000
![]() |
So let's stop using pointers altogether, eh? -- |
kazzmir
Member #1,786
December 2001
![]() |
Yea, welcome to Java/perl/python/ocaml/scheme/ruby/javascript/anything invented in the past 20 years. |
axilmar
Member #1,204
April 2001
|
anonymous said: The only thing to keep in mind is not to keep using the moved-from object It does not scale well in time (projects taking months or years to complete and changes over time) as well in space (programmers coming and going etc). This is what I am telling you. For a single programmer that can fit everything in his head, the problem is minimal. But for a big project, it's a disaster waiting to happen. |
anonymous
Member #8025
November 2006
|
Is there that much to fit into the head? Wouldn't it be enough to look at current function to know whether a move is good or not? (Completely unlike delete where either you have a very clear ownership policy or you are completely lost.) void foo(X&& x) { X other = std::move(x); x.bar(); //don't do this (using moved-from object) } void foobar(X& x) { foo(std::move(x)); //don't do this either (moving from lvalue reference without restoring x) }
|
bamccaig
Member #7,536
July 2006
![]() |
If a particular team is and has been capable of developing software in C++ then I don't see move semantics causing them problems. -- acc.js | al4anim - Allegro 4 Animation library | Allegro 5 VS/NuGet Guide | Allegro.cc Mockup | Allegro.cc <code> Tag | Allegro 4 Timer Example (w/ Semaphores) | Allegro 5 "Winpkg" (MSVC readme) | Bambot | Blog | C++ STL Container Flowchart | Castopulence Software | Check Return Values | Derail? | Is This A Discussion? Flow Chart | Filesystem Hierarchy Standard | Clean Code Talks - Global State and Singletons | How To Use Header Files | GNU/Linux (Debian, Fedora, Gentoo) | rot (rot13, rot47, rotN) | Streaming |
Thomas Fjellstrom
Member #476
June 2000
![]() |
kazzmir said: Yea, welcome to Java/perl/python/ocaml/scheme/ruby/javascript/anything invented in the past 20 years. Perl has pointers. It calls them references, but its the same thing. And if you feel really dirty, you can actually use real addresses, and turn it into a perl object. my $var = "SCALAR(0xdeadbeef)"; $$var = "foo"; # BAD! edit: I realize thats not actually how you do it, but its something like that, and something I've only done once in the past 10+ years I've been codeing in perl, so I don't remember how its done. -- |
kazzmir
Member #1,786
December 2001
![]() |
You're right, perl is just as bad as C. I should have known. |
axilmar
Member #1,204
April 2001
|
anonymous said: Is there that much to fit into the head? Wouldn't it be enough to look at current function to know whether a move is good or not? (Completely unlike delete where either you have a very clear ownership policy or you are completely lost.) It just does not scale well. If, in your example, the move call and the x.bar() call was a few pages apart, for example, then you might easily miss it. |
|
|