sob., 13 kwi 2019 o 07:16 Emil Dotchevski via Boost
On Fri, Apr 12, 2019 at 9:40 PM degski via Boost
wrote: On Sat, 13 Apr 2019 at 00:47, Vinnie Falco via Boost <
boost@lists.boost.org>
wrote:
If I want/need a variant that offers the never-empty basic guarantee then Boost should not provide it?
Andrzej argues (in the other post) that you *shouldn't want* it, becoz it masks UB [result of programmer error] and will now cause havoc elsewhere in the program.
The basic guarantee prevents UB, doesn't mask it.
Perhaps you mean to say "masks bugs", or at least that's how I read Andrzej's opinion. This may be so, but I fail to see why the argument against the basic guarantee in variant2 assignment does not apply in general. It would help me (and perhaps others) understand this argument if someone explains why is the basic guarantee appropriate in, say, the std::vector<T>::op=, but not in variant.
Let me clarify. I am not arguing against the basic guarantee. (I am all in favor of basic guarantee.) When I mention a hypothetical variant that enters a valueless_by_exception state, and later it is UB if its value is read, I still consider it a basic guarantee. It is just that such type has a weaker invariant than variant2. It is still considered basic, because you can perform the minimum set of operations: destroy it and reset it. My point is: - The weaker invariant *in the case of variant* does not impose the additional burden on programmers and does not require of them to put defensive if-statements before every use of the variant. (Therefore maybe it is better if this is described by two invariants: one for normal operations, and one for special-case situations.) - Basic never empty guarantee is no better than any other basic guarantee. I never argue that std::vector's invariant should be weaker than what it is now, because the invariant being stronger than necessary does not cost us any run-time or spatial performance. It is trivial to provide, does not increase the size of the vector, it does not require the vector to make additional allocations, it does not complicate the implementation a single bit. In fact, it would require efficiency compromises to provide another "partially defined" state. However, I still believe that anyone who observes the value of a vector that threw from its assignment has done their exception handling logic wrong. And maybe it would be beneficial if in debug mode (or some other special testing mode) vector contained a flag that it has thrown from any of its basic-guarantee operations; and an attempt to observe its value should be signaled with assertion. Regards, &rzej;