Boost logo

Boost :

From: Zach Laine (whatwasthataddress_at_[hidden])
Date: 2019-11-28 22:44:51


On Thu, Nov 28, 2019 at 9:52 AM Peter Dimov via Boost <boost_at_[hidden]>
wrote:

> Zach Laine wrote:
> > > 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[]?
>
> Nothing inherently makes it so. It just is, in the observable universe.
>
> > 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.
>
> Even if this only occurs 0.1% of the time, the design should cater to it
> because of the mere possibility?
>
> The flip side is the loss of efficiency when you do have to check. You
> need
> to compute the size of the argument twice, which in the char const* case
> isn't free.
>
> > 2) If the check is needed, can the programmer write code that can
> sensibly
> > deal with the problem?
>
> Sure, throw an exception. :-)
>
> > 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?
>
> No. I would "precondition" `op+=( char const (&)[ M ] )` (and op=) by
> failing at compile time when M > N, because the size is known, but in
> fixed_string's case, the size isn't known.
>
> There's no significant difference between accumulating the elements of
> vector<string> and those of vector<fixed_string> into a fixed_string. In
> both cases, we have no idea whether they'll fit or not. And yes, when they
> are known in advance, we can compute the final size in one loop, check,
> then
> += in a second loop, avoiding the check on each iteration. So there's a
> potential efficiency loss here, outweighed by gain of convenience and loss
> of buffer overflow exploits in the more common case where the accumulated
> strings come one by one from input.
>

Ok, I understand your point a bit better now I think. Is it the
unboundedly-large nature of a NTBS that has you concerned? That is, do you
think that op+=(char) should assert and op+=(char const *) should throw?
That position makes sense to me, thought I don't share it -- though I think
that's just taste. However, I cannot imagine why I'd ever want op+=(char)
or op+=(string_view) to throw.

Zach


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