Re: [Boost-users] [review][fixed_string] FixedString review starts today

classic Classic list List threaded Threaded
45 messages Options
123
Reply | Threaded
Open this post in threaded view
|

Re: [Boost-users] [review][fixed_string] FixedString review starts today

Boost - Dev mailing list
On Wed, Nov 27, 2019 at 11:56 AM Zach Laine via Boost-users <
[hidden email]> wrote:

> This appears quite wrong, even if Augustin is the one behind it.  Did he
> say why he expects that to work?  It looks like it accepts doubles as
> iterators, for instance.
>
> // Because k-ballo said so
> template<class T>
> using is_input_iterator =
>     std::integral_constant<bool, ! std::is_integral<T>::value>;
>

 This is presumably trying to follow [container.requirements.general]p17:

The extent to which an implementation determines that a type cannot be an
> input iterator is unspecified, except that as a minimum integral types
> shall not qualify as input iterators.

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: [Boost-users] [review][fixed_string] FixedString review starts today

Boost - Dev mailing list
On Fri, Nov 29, 2019 at 4:06 PM Tim Song via Boost
<[hidden email]> wrote:
> The extent to which an implementation determines that a type cannot be an
> > input iterator is unspecified, except that as a minimum integral types
> > shall not qualify as input iterators.

Wow, nice bit of archeological work there! Agustin right again, as usual.

Thanks

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: [Boost-users] [review][fixed_string] FixedString review starts today

Boost - Dev mailing list
In reply to this post by Boost - Dev mailing list
On Thu, Nov 28, 2019 at 6:18 PM Andrey Semashev via Boost <
[hidden email]> wrote:

> On 2019-11-29 01:44, Zach Laine via Boost wrote:
> >
> > 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.
>
> IIRC, append/insert/push_back will throw with any container or
> std::string, if the result exceeds max_size(). It is only natural if
> fixed_string does the same, it is the expected behavior.
>
> You can argue for a separate set of unsafe insert methods that don't
> perform the check and exhibit undefined behavior if the resulting length
> exceeds the limit. But it should be very clear that the user must ensure
> himself that it doesn't happen.
>

I don't find it natural that a type whose size is statically known and a
type whose size is not statically known have the same relationship to user
code (preconditions, use of UB vs. exceptions, etc.).

Zach

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: [Boost-users] [review][fixed_string] FixedString review starts today

Boost - Dev mailing list
Zach Laine wrote:

> I don't find it natural that a type whose size is statically known and a
> type whose size is not statically known have the same relationship to user
> code (preconditions, use of UB vs. exceptions, etc.).

But the size of the proposed fixed_string isn't statically known. Its
capacity is.


_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: [Boost-users] [review][fixed_string] FixedString review starts today

Boost - Dev mailing list
In reply to this post by Boost - Dev mailing list
On Fri, Nov 29, 2019 at 1:15 AM Peter Dimov via Boost <[hidden email]>
wrote:

> Zach Laine wrote:
>
> > 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?
>
> No, I prefer all of them consistently throwing, even when the check is
> O(1).
> My primary concern is not the loss of efficiency due to double checking,
> it's to avoid buffer overflow exploits.
>

Ok, so the issue as you see it is that a program that is memory unsafe
should die in release builds rather than allowing an attacker to take over,
is that right?  If so, I understand the motivation, but I don't share it --
I literally do not ever need to worry about such things in my work.  Should
everyone pay the checking cost, because this is a concern for some code
(even if it is a common concern -- I'm not minimizing it more than to say
that it's <100% of uses).

Moreover, you mention using __builtin_trap below, which gives you a quick
death instead of acting as an attack vector, but the proposed design does
not.  Again I ask, if we throw in this case, what do I write in catching
code to remediate the situation that I need to stuff 10lbs of bits into a
5lb sack?


> Yes, this will be less efficient if you += characters (but not by so much
> as
> one might think), and yes, you can write code that will be correct if op+=
> doesn't check. (Since operating on chars destroys optimizations due to
> aliasing, the inner loop improves from
>
> .L5:
>         add     rax, 1
>         movzx   ecx, BYTE PTR [rdx]
>         cmp     rax, 511
>         ja      .L11
>         add     rdx, 1
>         mov     QWORD PTR [rdi], rax
>         mov     BYTE PTR [rdi+7+rax], cl
>         cmp     rsi, rdx
>         jne     .L5
>
> https://godbolt.org/z/Z37Pmx
>
> to
>
> .L3:
>         movzx   ecx, BYTE PTR [rdx+rax]
>         add     rax, 1
>         mov     QWORD PTR [rdi], rax
>         mov     BYTE PTR [rdi+7+rax], cl
>         cmp     r8, rax
>         jne     .L3
>
> https://godbolt.org/z/CXHRKQ
>
> which is better, but far from optimal.)
>

Ok, I tried this myself on Quickbench:

http://quick-bench.com/WZPNHFBKI-hFxThBYRZVjndtBho

I see a slowdown factor of 1.39 when throwing if a single newly appended
character (the char op+= case) does not fit, vs. UB.  UB is our friend
here.  It would be a shame if this code:

std::ranges::copy(r, std::back_inserter(str));

(for some fixed_string str) were 1.39x slower, if I know that r is smaller
than str's capacity, and str is empty.


> I were implementing this class, I would always check in op+= (and append
> etc) even if the specification says "Expects" instead of "Throws", I'd
> just
> __builtin_trap instead of throwing. Otherwise, this is strcat all over
> again, and there's a reason there was a big concerted push against this
> style in/by Microsoft and elsewhere.
>

Zach

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: [Boost-users] [review][fixed_string] FixedString review starts today

Boost - Dev mailing list
In reply to this post by Boost - Dev mailing list
On Fri, Nov 29, 2019 at 2:39 AM Andrzej Krzemienski via Boost <
[hidden email]> wrote:

> I suspect (I am not programming in an embedded system) that rather than
> relying on __builtin_trap() or std::abort(), what you do is start treating
> a `resize()` over `capacity()` as a precondition violation (a bug). And
> this causes a different programming model and the organization of your
> code.
>

Yes, this is exactly my claim as well.

Zach

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: [Boost-users] [review][fixed_string] FixedString review starts today

Boost - Dev mailing list
In reply to this post by Boost - Dev mailing list
On Fri, Nov 29, 2019 at 3:10 AM Peter Dimov via Boost <[hidden email]>
wrote:

> Andrzej Krzemienski wrote:
>
> > I suspect (I am not programming in an embedded system) that rather than
> > relying on __builtin_trap() or std::abort(), what you do is start
> treating
> > a `resize()` over `capacity()` as a precondition violation (a bug). And
> > this causes a different programming model and the organization of your
> > code.
>
> That was exactly why I wrote
>
> > > There's no need to afford exceptions, you just need to be able to
> afford
> > > the potential loss in performance, basically one branch per append if
> > > not heroically optimized away.
>
> That is: in order to use the library as presented, you don't need to
> afford
> exceptions, but you will need to basically duplicate the same check op+=
> does, in user code; this may decrease performance, but will not allow a
> buffer overflow in case you either forgot the check or got it wrong.
>

This leaves out the case where you know from context outside of
fixed_string that an append is guaranteed to work.  This is an important
case, IMO, and one for which I should not be required to suffer the perf
overhead when I don't need the check.

Also, if the API defined preconditions and invoked UB when misused, the
check would only ever need to happen once.  As you say, this would have to
be done in user code -- as with all precondtioned functions, like back(),
operator[](), etc.  That is, the user's need to verify that the operation
will succeed would not be unique to the append/insert operations.

Zach

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: [Boost-users] [review][fixed_string] FixedString review starts today

Boost - Dev mailing list
In reply to this post by Boost - Dev mailing list
On Fri, Nov 29, 2019 at 6:15 PM Vinnie Falco via Boost <
[hidden email]> wrote:

> On Fri, Nov 29, 2019 at 4:06 PM Tim Song via Boost
> <[hidden email]> wrote:
> > The extent to which an implementation determines that a type cannot be an
> > > input iterator is unspecified, except that as a minimum integral types
> > > shall not qualify as input iterators.
>
> Wow, nice bit of archeological work there! Agustin right again, as usual.
>

I don't think that's the take-away.  "unspecified" does not mean that a
good implementation only checks that the type is not an integral type.  It
just means that they don't document whatever they do, as they would with
"implementation-defined".  It also does not mean that a Boost library
(which is not an implementation) should accept "double" as an iterator!

Zach

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: [Boost-users] [review][fixed_string] FixedString review starts today

Boost - Dev mailing list
In reply to this post by Boost - Dev mailing list
On Mon, Dec 2, 2019 at 11:48 AM Peter Dimov via Boost <[hidden email]>
wrote:

> Zach Laine wrote:
>
> > I don't find it natural that a type whose size is statically known and a
> > type whose size is not statically known have the same relationship to
> user
> > code (preconditions, use of UB vs. exceptions, etc.).
>
> But the size of the proposed fixed_string isn't statically known. Its
> capacity is.
>

Right, thanks.  I wrote "size" when I meant "capacity".  I think the point
remains the same, however.  I know statically how much room I have in which
to operate, as opposed to having a runtime-variable amount of room.

Zach

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: [Boost-users] [review][fixed_string] FixedString review starts today

Boost - Dev mailing list
In reply to this post by Boost - Dev mailing list
Zach Laine wrote:
> Ok, I tried this myself on Quickbench:
>
> http://quick-bench.com/WZPNHFBKI-hFxThBYRZVjndtBho

I tried to fix that to add the null terminator, but as a result both
push_backs were entirely optimized away.

http://quick-bench.com/DtPR9Yov1TSzUFeYRx0ipVvUYBk

The Append case is how I think this code should be written. Character by
character loops are only useful as a worst-case estimate; if there's a
performance problem there, you'd rewrite the loop to not push_back
characters one by one, not try to make it go faster.


_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: [Boost-users] [review][fixed_string] FixedString review starts today

Boost - Dev mailing list
In reply to this post by Boost - Dev mailing list
> > Zach Laine wrote:
> > Ok, I tried this myself on Quickbench:
> >
> > http://quick-bench.com/WZPNHFBKI-hFxThBYRZVjndtBho
>
> I tried to fix that to add the null terminator, but as a result both
> push_backs were entirely optimized away.
>
> http://quick-bench.com/DtPR9Yov1TSzUFeYRx0ipVvUYBk

Wait, I forgot to increment the size!

http://quick-bench.com/sI71NY7OpQ8ft27HpELko8q_4xM

Not much improvement anyway.


_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: [Boost-users] [review][fixed_string] FixedString review starts today

Boost - Dev mailing list
In reply to this post by Boost - Dev mailing list
> Wait, I forgot to increment the size!
>
> http://quick-bench.com/sI71NY7OpQ8ft27HpELko8q_4xM
>
> Not much improvement anyway.

This one at least does something:

http://quick-bench.com/g_-BAIENMHQ1Pi1d136FBdp0idQ

It still measures nothing though; the string isn't actually written.

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: [Boost-users] [review][fixed_string] FixedString review starts today

Boost - Dev mailing list
In reply to this post by Boost - Dev mailing list
> This one at least does something:
>
> http://quick-bench.com/g_-BAIENMHQ1Pi1d136FBdp0idQ
>
> It still measures nothing though; the string isn't actually written.

Finally, this one actually bothers to write the characters:

http://quick-bench.com/-FUFkLtQeEa3brMf-y139G3Bbcg

Quickbenches aren't very representative.

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: [Boost-users] [review][fixed_string] FixedString review starts today

Boost - Dev mailing list
In reply to this post by Boost - Dev mailing list
Zach Laine wrote:

> Ok, so the issue as you see it is that a program that is memory unsafe
> should die in release builds rather than allowing an attacker to take
> over, is that right?

Yes, this is known as converting a remote execution exploit into a denial of
service exploit. Not great, not terrible.

> If so, I understand the motivation, but I don't share it -- I literally do
> not ever need to worry about such things in my work.  Should everyone pay
> the checking cost, because this is a concern for some code (even if it is
> a common concern -- I'm not minimizing it more than to say that it's <100%
> of uses).

It's a very, very common concern; it was actually the #1 security issue (and
maybe still is.) As I said, this was the primary motivation behind
Microsoft's security initiative with their _s functions, and they took this
exact same approach - all strcpy-like functions check for buffer overrun and
terminate. This is a practically unquestioned security best practice.

> Moreover, you mention using __builtin_trap below, which gives you a quick
> death instead of acting as an attack vector, but the proposed design does
> not.  Again I ask, if we throw in this case, what do I write in catching
> code to remediate the situation that I need to stuff 10lbs of bits into a
> 5lb sack?

It's hard to answer this without context. The simplest possible case would
be

void append_something( char const * p, std::size_t n, error_code & ec )
noexcept
{
    if( buffer_.size() + n > buffer_.max_size() )
    {
        ec = make_error_code( errc::invalid_argument );
        return;
    }

    buffer_.append( p, n );
    ec = {};
}

This goes straight to terminate regardless of whether append aborts or
throws, because of the noexcept. And yes, this can happen, because I have a
bug in my size check, as 99% of all people would.

In a system that uses exceptions instead of error codes, the functions won't
be noexcept, but then you'd just let the length_error bubble up, as with any
other failure. If you for instance try to serialize a 10lb json into a
fixed_string<5lb>, the serialization will fail with an exception and you'll
need to figure out what to do with that failure, as with any other. This is
no different from giving a fixed storage allocator to some std::vector (or
to the JSON deserializer, if you will.)


_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: [Boost-users] [review][fixed_string] FixedString review starts today

Boost - Dev mailing list
In reply to this post by Boost - Dev mailing list
On 3/12/2019 07:02, Zach Laine wrote:

> On Mon, Dec 2, 2019 at 11:48 AM Peter Dimov wrote:
>
>> Zach Laine wrote:
>>
>>> I don't find it natural that a type whose size is statically known and a
>>> type whose size is not statically known have the same relationship to
>>> user code (preconditions, use of UB vs. exceptions, etc.).
>>
>> But the size of the proposed fixed_string isn't statically known. Its
>> capacity is.
>
> Right, thanks.  I wrote "size" when I meant "capacity".  I think the point
> remains the same, however.  I know statically how much room I have in which
> to operate, as opposed to having a runtime-variable amount of room.

But given fixed_string<N> and fixed_string<M>, there is no way to
determine at compile time whether direct concatenation is safe or will
overflow, even presuming you are appending to the larger of the two.

The only way to guarantee at compile time that a concatenation is not at
risk of overflow is to first copy to a fixed_string<N+M> and then
append, which (in the primary intended use case of allocating a large
buffer up-front and not using most of it) is a massive waste of both
performance and memory.

Thus (assuming we're appending into one of the existing buffers
instead), *someone* needs to do a range check at runtime, and forgetting
it is a serious security vulnerability.  If we lived in a world where
sanitisers were readily available, reliable, and automatically run on
all code, then maybe you can argue that this is the user's
responsibility and UB is "safe".  We still do not yet live in that world.

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: [Boost-users] [review][fixed_string] FixedString review starts today

Boost - Dev mailing list
In reply to this post by Boost - Dev mailing list
On Mon, Dec 2, 2019 at 11:59 AM Zach Laine via Boost <[hidden email]>
wrote:

> On Fri, Nov 29, 2019 at 6:15 PM Vinnie Falco via Boost <
> [hidden email]> wrote:
>
> > On Fri, Nov 29, 2019 at 4:06 PM Tim Song via Boost
> > <[hidden email]> wrote:
> > > The extent to which an implementation determines that a type cannot be
> an
> > > > input iterator is unspecified, except that as a minimum integral
> types
> > > > shall not qualify as input iterators.
> >
> > Wow, nice bit of archeological work there! Agustin right again, as usual.
> >
>
> I don't think that's the take-away.  "unspecified" does not mean that a
> good implementation only checks that the type is not an integral type.  It
> just means that they don't document whatever they do, as they would with
> "implementation-defined".  It also does not mean that a Boost library
> (which is not an implementation) should accept "double" as an iterator!
>
> Zach
>
>
This specification is only used to disambiguate (size_t, value_type) and
(Iter, Iter) overloads.

Having (double, double) go to the latter and explode at compile time might
not be a bad thing.

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: [Boost-users] [review][fixed_string] FixedString review starts today

Boost - Dev mailing list
In reply to this post by Boost - Dev mailing list
I wonder if it is possible to implement op+ such that if one writes:

x = a+b;

the return value of a+b gets converted to the type of x. The motivation is
that, as a user, I've determined a fixed size limit for x, and therefore
the library should use that, and if it is exceeded at run-time, it makes
sense for the behavior to be the same as when any other fixed_string
capacity is exceeded (e.g. boost::throw_exception).

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: [Boost-users] [review][fixed_string] FixedString review starts today

Boost - Dev mailing list
On 3/12/2019 15:46, Emil Dotchevski wrote:
> I wonder if it is possible to implement op+ such that if one writes:
>
> x = a+b;
>
> the return value of a+b gets converted to the type of x. The motivation is
> that, as a user, I've determined a fixed size limit for x, and therefore
> the library should use that, and if it is exceeded at run-time, it makes
> sense for the behavior to be the same as when any other fixed_string
> capacity is exceeded (e.g. boost::throw_exception).

It is possible, by using a deferred execution pattern.

operator+ would return a unique type which contains the references to a
and b (not yet concatenated) and implements a templated implicit cast
operator for fixed_string<N>, which is where the concatenation is
actually performed (since it then knows the target type).

This also works when passing parameters -- at least when those
parameters are declared with an explicit fixed_string<N> type.

The caveat is that it doesn't work with "auto" variables, or with
templated parameters.  This limitation unfortunately is quite a large
one, and can be quite aggravating in practice.

(Another caveat is that those cases that "don't work" above can easily
cause dangling references and other lifetime issues instead of cleanly
failing to compile.)

Given that, I don't think I'd recommend actually doing it.


The reference-lifetime-safe alternative is to return an object that
contains a copy of the parameters, but this is now strictly worse than
just returning a fixed_string<A+B>.  (And, when you then try to assign
this to a fixed_string<N>, reintroduces the problem of what to do when
a.size()+b.size() > N, since it will probably often be the case that A+B
 > N, and this is not a mistake.)

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: [Boost-users] [review][fixed_string] FixedString review starts today

Boost - Dev mailing list
Right, that's what I meant. Dangers, issues with auto aside, I can't think
of a use case when I would want op+ to return a string of size M+N. Keep in
mind, op+ composes. Leaving it undefined is an option, I suppose.

On Mon, Dec 2, 2019 at 7:59 PM Gavin Lambert via Boost <
[hidden email]> wrote:

> On 3/12/2019 15:46, Emil Dotchevski wrote:
> > I wonder if it is possible to implement op+ such that if one writes:
> >
> > x = a+b;
> >
> > the return value of a+b gets converted to the type of x. The motivation
> is
> > that, as a user, I've determined a fixed size limit for x, and therefore
> > the library should use that, and if it is exceeded at run-time, it makes
> > sense for the behavior to be the same as when any other fixed_string
> > capacity is exceeded (e.g. boost::throw_exception).
>
> It is possible, by using a deferred execution pattern.
>
> operator+ would return a unique type which contains the references to a
> and b (not yet concatenated) and implements a templated implicit cast
> operator for fixed_string<N>, which is where the concatenation is
> actually performed (since it then knows the target type).
>
> This also works when passing parameters -- at least when those
> parameters are declared with an explicit fixed_string<N> type.
>
> The caveat is that it doesn't work with "auto" variables, or with
> templated parameters.  This limitation unfortunately is quite a large
> one, and can be quite aggravating in practice.
>
> (Another caveat is that those cases that "don't work" above can easily
> cause dangling references and other lifetime issues instead of cleanly
> failing to compile.)
>
> Given that, I don't think I'd recommend actually doing it.
>
>
> The reference-lifetime-safe alternative is to return an object that
> contains a copy of the parameters, but this is now strictly worse than
> just returning a fixed_string<A+B>.  (And, when you then try to assign
> this to a fixed_string<N>, reintroduces the problem of what to do when
> a.size()+b.size() > N, since it will probably often be the case that A+B
>  > N, and this is not a mistake.)
>
> _______________________________________________
> Unsubscribe & other changes:
> http://lists.boost.org/mailman/listinfo.cgi/boost
>

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: [Boost-users] [review][fixed_string] FixedString review starts today

Boost - Dev mailing list
In reply to this post by Boost - Dev mailing list
On Mon, Dec 2, 2019 at 5:42 PM Gavin Lambert via Boost <
[hidden email]> wrote:

> On 3/12/2019 07:02, Zach Laine wrote:
> > On Mon, Dec 2, 2019 at 11:48 AM Peter Dimov wrote:
> >
> >> Zach Laine wrote:
> >>
> >>> I don't find it natural that a type whose size is statically known and
> a
> >>> type whose size is not statically known have the same relationship to
> >>> user code (preconditions, use of UB vs. exceptions, etc.).
> >>
> >> But the size of the proposed fixed_string isn't statically known. Its
> >> capacity is.
> >
> > Right, thanks.  I wrote "size" when I meant "capacity".  I think the
> point
> > remains the same, however.  I know statically how much room I have in
> which
> > to operate, as opposed to having a runtime-variable amount of room.
>
> But given fixed_string<N> and fixed_string<M>, there is no way to
> determine at compile time whether direct concatenation is safe or will
> overflow, even presuming you are appending to the larger of the two.
>
> The only way to guarantee at compile time that a concatenation is not at
> risk of overflow is to first copy to a fixed_string<N+M> and then
> append, which (in the primary intended use case of allocating a large
> buffer up-front and not using most of it) is a massive waste of both
> performance and memory.
>

All true, but I'm unclear why you're pointing this out.  I never suggested
otherwise.


> Thus (assuming we're appending into one of the existing buffers
> instead), *someone* needs to do a range check at runtime, and forgetting
> it is a serious security vulnerability.  If we lived in a world where
> sanitisers were readily available, reliable, and automatically run on
> all code, then maybe you can argue that this is the user's
> responsibility and UB is "safe".  We still do not yet live in that world.
>

I get the point you're making.  What I do not get is why you *only* apply
it to op+.  That is, if memory is so essential for op+, then why is it not
also essential for op[] . This is not a troll.  I really do want to know
what the difference is as you see it.

Zach

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
123