On Sat, May 27, 2017 at 4:09 PM, Andrzej Krzemienski via Boost < boost@lists.boost.org> wrote:
2017-05-28 0:55 GMT+02:00 Emil Dotchevski via Boost
:
On Sat, May 27, 2017 at 3:15 PM, Andrzej Krzemienski via Boost <> Note that there is no provision to report a failure (to establish the invariants) except by throwing. This is not an omission but a deliberate design choice.
Interesting. I do not know what you mean here. Maybe, "there is no other way to report such failure except to throw an exception"? If so, I agree, but how does this relate to the discussed topic?
What I am demonstrating is that the C++ semantics for initialization and destruction of objects have a built-in assumption about what constitutes a valid object. Can you define this as "the only safe thing to do with x is call is_valid()" on it? Sure, but then you're operating as a C programmer. Consider what a C programmer has to do: struct foo { /*state*/ }; void init_foo( foo * x ) { /*initialization*/ assert(is_valid(x)); } void destroy_foo( foo * x ) { assert(is_valid(x)); //destroy *x } void use_foo( foo * x ) { assert(is_valid(x)); /*use foo*/ } And now compare this to a C++ program: struct foo { /*state*/ foo() { /*initialization*/ } ~foo() { /*destruction*/ } void use() { /*use foo*/ } }; Note that in well designed C++ programs not only the asserts are not necessary, they're downright silly. Is the object valid? Duh, of course it is, or else the constructor would not have returned. But if you introduce a "not quite valid" state, not only you need the asserts, you're making it much more difficult for the user to reason about the state of the objects in his program, just like a C programmer must. If the user is handed an object, is it safe to use it? He could assume that it is, but your design choice has rendered that an unsafe assumption, because you're effectively reserving the right for the object to be unusable. Alternatively, he could assume that he can't use it unless he checks first. But now he's forced to write if( obj.is_valid() ) obj.use() rather than obj.use(). What he is supposed to do in theory is analyze the program carefully and determine for sure if in this particular case the object can be unusable. In practice, there are so many corner cases that it is easy to get this wrong, if not when the code is initially written, then under maintenance. Such bugs are very difficult to detect, and infinitely more difficult to detect in error handling code (where this "not quite valid" state would occur, per your design.) Granted, we're discussing a library specifically designed to support programming without exceptions, so we're already in C territory as far as object state is concerned. Emil