Boost logo

Boost :

From: Zach Laine (whatwasthataddress_at_[hidden])
Date: 2019-11-27 18:25:35


On Wed, Nov 27, 2019 at 11:23 AM Peter Dimov <pdimov_at_[hidden]> wrote:

> Zach Laine wrote:
> > On Wed, Nov 27, 2019 at 11:01 AM Peter Dimov via Boost
> > <boost_at_[hidden]> 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


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk