Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

> Only if that connection object doesn’t support move — we’re 12 years of C++ standards past the arrival of move, and it still leaves its source in an indeterminate state.

I haven’t watched the streams he referred to, but… I am fairly certain the language itself says no such thing. You may be thinking of the standard library, which states that certain classes of moved-from objects have unspecified state. If you’re writing your own DB connection class, you can define moves to leave the object in whatever state you prefer, or disallow moves.

Admittedly it’s still a weird example IMO, because external factors can sever the connection while the object is in scope.



There is literally no correct way to handle move in an RAII context that doesn’t either (a) behave unexpectedly if you try to use the moved-from object or (b) permit a null value of the object. This isn’t a library problem — it’s a language problem.


What if the moved-from DB object lazily opens a new connection, if someone uses it again? Maybe that’s a null object, but at least the nullness isn’t really observable to the API user. Even the extra latency or possibility of failing to connect must be expected at any time from query() etc. so it changes little.

Also, I would say nothing is “unexpected” behavior if you document it and implement accordingly. And at least for this DB case, handling it is not onerous or stretching the idea of class invariants beyond usability.

I’m probably like what GP said, “high on the feeling of having finally grokked C++, which is no small feat.” But I either want to understand better why move is broken, or we can agree that things like move require too much skill to get right and there are better alternative languages.


> What if the moved-from DB object lazily opens a new connection, if someone uses it again?

Great, so now the stateful settings on my database connection change depending on whether I move from it.

Database connections are kind of a bad example — having a connection drop is not really unexpected behavior, and a program that uses a database should be prepared for a connection to drop, so there’s kind of an invalid state on a connection anyway. But things like file handles or mutex guards aren’t like this — it’s reasonable to expect that, on a functioning system, a file handle won’t go away. And if I’m using a type-safe language that supports RAII, I would like the compiler to ensure that I can’t use an object that isn’t in a valid state.

Rust can do this, as can lots of languages that support “affine” types (that name is absurd). GC languages can kind of do this too, as long as cloning the reference is considered valid. Languages with “linear” types can even statically guarantee that I don’t forget to close my object.

C++ can ensure that an object is valid if it’s in scope, but only if that object is not movable, so “consume” operations are not possible in a type-safe way.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: