Re: [boost] [Boost-users] [review][fixed_string] FixedString review starts today
and yes, you can write code that will be correct if op+= doesn't check.
Maybe you can, but I apparently can't. This is what I just wrote: void my_append( fixed_string<512> & s, std::string_view s1, std::string_view s2 ) { if( s.size() + s1.size() + s2.size() > s.max_size() ) throw std::length_error( "" ); s += s1; s += s2; } Is this correct? (Spoiler: no.)
On 2019-11-29 11:12, Peter Dimov via Boost wrote:
and yes, you can write code that will be correct if op+= doesn't check.
Maybe you can, but I apparently can't. This is what I just wrote:
void my_append( fixed_string<512> & s, std::string_view s1, std::string_view s2 ) { if( s.size() + s1.size() + s2.size() > s.max_size() ) throw std::length_error( "" );
s += s1; s += s2; }
Is this correct? (Spoiler: no.)
I think, appending N strings still requires N tests, unless you know that the string sizes combined don't overflow. size_t size_left = s.max_size() - s.size(); if (s1.size() > size_left) throw_length_error(); size_left -= s1.size(); if (s2.size() > size_left) throw_length_error(); Or use unsigned __int128 to calculate the combined size. Alas, it's not universally available.
Andrey Semashev wrote:
void my_append( fixed_string<512> & s, std::string_view s1, std::string_view s2 ) { if( s.size() + s1.size() + s2.size() > s.max_size() ) throw std::length_error( "" );
s += s1; s += s2; }
Is this correct? (Spoiler: no.)
I think, appending N strings still requires N tests, unless you know that the string sizes combined don't overflow.
size_t size_left = s.max_size() - s.size(); if (s1.size() > size_left) throw_length_error(); size_left -= s1.size(); if (s2.size() > size_left) throw_length_error();
Exactly. And the easiest and most readable way to get it right is just to do the same op+= already would: if( s1.size() > s.max_size() - s.size() ) throw std::length_error( "" ); s += s1; if( s2.size() > s.max_size() - s.size() ) throw std::length_error( "" ); s += s2; Incidentally, all the checks in the library seem wrong for this reason (they check `size() + m > max_size()` instead of `m > max_size() - size()`.)
participants (2)
-
Andrey Semashev
-
Peter Dimov