On Friday 18 January 2008 11:20, Ulrich Eckhardt wrote:
> On Thursday 17 January 2008, Petr Ovtchenkov wrote:
> > string s;
> > string e;
> >
> > string::size_type p = s.find( e );
> >
> > if ( p != string::npos ) {
> > // normal: no reasons to check e.size(), because p
> > // is within s, and s' function say 'ok'
> > char ch = s[p]; // <- out-of-bound, if p is 0
> > }
>
> Sorry, but that code is broken, no matter what find() returns. With the same
> reasoning you could access other elements like s[p+1], which is an invalid
> assumption because it assumes a certain length of the searched sequence.
> Correct code takes into account that you can only access s[p+n] for
> n<e.size() and if e.size()==0 there are no elements that can be accessed --
> simple as that.
I focus on p (not on some operations under p) due to this is position
within string s. If s.find return position within itself, and this
position not marked as 'no position' (npos), I reasonably assume that
this is valid position. Any checks of state of 'e', to ensure that
p (position within string s, returned by s' method!) is valid, looks
like bogus joke. Return of really invalid position is in contrast
with STL spirit. That's why I think this is standard defect.
BTW, I suspect that if string().find(string()) could return npos,
then code, that correctly process mentioned marginal case, could
process fine too.
>
> Also, though that is mostly beside the point, I can't imagine any use for code
> like the above. If you are only checking if e is contained in s, the result
> is probably meaningless if e is empty and application logic dictates that you
> check that first. If you want to e.g. replace or delete the sequence, you
> either use substr(), which works correctly, or you are using e.size()
> elements from the returned position, which still works correctly. I think the
> fact that two other major standardlibraries behave like the second
> interpretation is at least a hint that it doesn't break application code,
> even though it is not a proof that they are correct.
I don't discuss any logic outside this sample of code. It doesn't have matter.
>
> > According to standard, string::rfind has the same behaviour as find,
> > but string::find_first*, string::find_last* return either valid position
> > or npos.
>
> Do they do so according to the implementation or according to the standard?
In standard rfind has similar caluse as find, while find_first* find_last* has
clause, that exclude such behaviour:
<snip>
21.3.6.4 basic_string::find_last_of [lib.string::find.last.of]
size_type
find_last_of(const basic_string<charT,traits,Allocator>& str,
size_type pos = npos) const;
Effects: Determines the highest position xpos, if possible, such that both
of the following conditions obtain:
- xpos <= pos and xpos < size();
- at(xpos) == str.at(I) for some element I of the string controlled by str.
</snip>
- ptr
|