On Wed, Nov 27, 2019 at 11:23 AM Peter Dimov
Zach Laine wrote:
On Wed, Nov 27, 2019 at 11:01 AM Peter Dimov via Boost
wrote: Zach Laine wrote:
Throwing when the capacity would be exceeded is wrong.
No, it's not. It's correct. It's a runtime error, not a programming time error.
Then why doesn't vector::operator[] throw? In either case, you know what the precondition is, and how to check it. That's what makes this a user error.
What makes op[] a user error is that the index rarely comes from external input. It typically comes from a variable that the programmer controls and program logic ensures is in range.
I disagree. What puts vector::operator+ inherently (which is directly analogous to fixed_string::operator+) more out of programmer control than vector::operator[]? Moreover, there are two things to consider: 1) Can I use this function within a context in which I know that the precondition check/throwing condition is not needed? This is in part an efficiency concern, of course. If I can check the condition myself, outside of the function, I can write code that maintains the invariant that the precondition is always true, or in which the precondition is true within some limited scope. I can then call the function within that invariant-maintaining code or scope, and elide the branches of the check. 2) If the check is needed, can the programmer write code that can sensibly deal with the problem? When I'm out of memory, I *may* be able to do something about that, depending on my system. For instance, running out of memory on a game console is not an unusual thing, and I'll have a failover strategy for that. Running out of array-based storage is not as easily recoverable. Unless the answers are 1) no and 2) yes, the function should not throw. Whereas when you += strings into a fixed capacity buffer, those are only
occasionally programmer-supplied. Program logic is not violated if the input strings exceed the buffer.
Ok, then do you advocate that fixed_string::operator+=(fixed_string) have preconditions and not throw, and that fixed_string::operator+=(char const *) should throw instead? Only the latter could have come from an end-user. End users have no way of supplying fixed_strings to your program.
Or stated differently, if in 90% of the cases the correct use of a function would involve the programmer writing out the exact same
if( !precondition ) throw exception();
thing that the function would have done itself were it throwing, the function should be throwing.
I can get behind that. I just don't think that I'd need to check-and-throw everywhere that I would use fixed_string::operator+=.
Whereas when you do `for( int i = 0; i < n; ++i ) { something with v[i]; }`, you don't need to insert the above before each [].
On this we agree. Zach