Another testsuite patch and a bug in string.find

brent verner brent@rcfile.org
Tue Jun 13 21:26:00 GMT 2000


on Tue, Jun 13, 2000 at 04:45:49PM -0700, Benjamin Kosnik typed aloud:
| 
| Nathan, did you get a chance to review this? If this is indeed a bug, or a
| change in this behavior is necessary, then perhaps string should be fixed?

I'm definitely not Nathan, but I my interpretation is that 
string::npos should be returned whenever 'b' is not found in 'a'
in the example (way) below... 

we are returning a.size() whenever we don't find a substring of 'a' 
equal to 'b' because we are testing eq('\000','\000') at the end 
of 'a'. 

Question: can std::string _contain_ a '\000'? If so, quit reading, 
cause I'm assuming '\000' is _seriously_ special :)

21.3.6.1 basic_string::find

[second requirement for a successful find(str,i)]
   at(xpos + I) == str.at(I) for all elements I of the string 
      controlled by str.

now, I see nowhere that deals with handling an empty string, but
it makes sense to me to be able to say, in all cases...

pos = a.find(b,i);
if( pos == string::npos ){
  // b was not found.
}

[return definition]
   2 Returns: xpos if the function can determine such a value for xpos. 
      Otherwise, returns npos.

and in my eyes, never will 'nothing == something'. we can accomplish
this currently by making the following change to bits/string.tcc

======================================================================
*** libstdc++-v3/bits/string.tcc	Fri Jun  2 21:52:32 2000
--- /usr/local/opt/include/g++-v3/bits/string.tcc	Wed Jun 14 00:06:12 2000
*************** namespace std
*** 602,608 ****
        size_t __xpos = __pos;
        const _CharT* __data = _M_data();
        for (; __xpos + __n <= this->size(); ++__xpos)
! 	if (traits_type::eq(__data[__xpos], *__s)
  	    && traits_type::compare(__data + __xpos, __s, __n) == 0)
  	  return __xpos;
        return npos;
--- 602,609 ----
        size_t __xpos = __pos;
        const _CharT* __data = _M_data();
        for (; __xpos + __n <= this->size(); ++__xpos)
! 	if ( __data[__xpos]
! 	    && traits_type::eq(__data[__xpos], *__s)
  	    && traits_type::compare(__data + __xpos, __s, __n) == 0)
  	  return __xpos;
        return npos;
======================================================================

my $.002
  brent

| > include <iostream>
| > #include <string>
| >  
| > int main()
| > {
| >     std::string a("hello");
| >     std::string b;
| >  
| >     for(unsigned i=0;i<=a.size();++i)
| >         std::cout<<a.find(b,i)<<std::endl;
| > }
| >  
| > Expected output:
| > 0
| > 1
| > 2
| > 3
| > 4
| > 4294967295
| >  
| > libstdc++-v3 output:
| > 5
| > 5
| > 5
| > 5
| > 5
| > 5
| > 
| > Anthony
| > 
| > testsuite/21_strings/find.cc: Empty strings can be found at all
| > positions
| > 
| > Index: find.cc
| > ===================================================================
| > RCS file: /cvs/gcc/egcs/libstdc++-v3/testsuite/21_strings/find.cc,v
| > retrieving revision 1.1
| > diff -u -p -r1.1 find.cc
| > - --- find.cc     2000/04/21 20:33:33     1.1
| > +++ find.cc     2000/06/07 10:36:09
| > @@ -56,21 +56,22 @@ bool test01(void)
| >    test &= csz01 == 8;
| >    csz01 = str01.find(str03, 12);
| >    test &= csz01 == npos;
| > - -  // It is implementation-defined if a given string contains an
| > empty
| > - -  // string. The only two times a char_type() (== empty string)
| > ending
| > - -  // element is required to be part of the string is on c_str() and
| > - -  // operator[size()] const: the indeterminate, stored state of the
| > - -  // string can vary, and not include a terminal char_type().
| > +
| > +  // An empty string consists of no characters
| > +  // therefore it should be found at every point in a string,
| > +  // except beyond the end
| >    csz01 = str01.find(str04, 0);
| > - -  test &= csz01 == npos || csz01 == str01.size();
| > +  test &= csz01 == 0; 
| >    csz01 = str01.find(str04, 5);
| > - -  test &= csz01 == npos || csz01 == str01.size();
| > +  test &= csz01 == 5; 
| > +  csz01 = str01.find(str04, str01.size());
| > +  test &= csz01 == npos; 
| >    
| >    // size_type find(const char* s, size_type pos, size_type n)
| > const;
| >    csz01 = str01.find(str_lit01, 0, 3);
| >    test &= csz01 == 0;
| >    csz01 = str01.find(str_lit01, 3, 0);
| > - -  test &= csz01 == npos;
| > +  test &= csz01 == 3; // zero length string should be found at pos
| >  
| >    // size_type find(const char* s, size_type pos = 0) const;
| >    csz01 = str01.find(str_lit01);
| > @@ -107,15 +108,15 @@ bool test01(void)
| >    csz01 = str01.find_first_of(str05, 4);
| >    test &= csz01 == 4;
| >  
| > - -  // It is implementation-defined if a given string contains an
| > empty
| > - -  // string. The only two times a char_type() (== empty string)
| > ending
| > - -  // element is required to be part of the string is on c_str() and
| > - -  // operator[size()] const: the indeterminate, stored state of the
| > - -  // string can vary, and not include a terminal char_type().
| > +  // An empty string consists of no characters
| > +  // therefore it should be found at every point in a string,
| > +  // except beyond the end
| > +  // However, str1.find_first_of(str2,pos) finds the first character
| > in 
| > +  // str1 (starting at pos) that exists in str2, which is none for
| > empty str2
| >    csz01 = str01.find_first_of(str04, 0);
| > - -  test &= csz01 == npos || csz01 == str01.size();
| > +  test &= csz01 == npos; 
| >    csz01 = str01.find_first_of(str04, 5);
| > - -  test &= csz01 == npos || csz01 == str01.size();
| > +  test &= csz01 == npos; 
| >    
| >    // size_type find_first_of(const char* s, size_type pos, size_type
| > n) const;
| >    csz01 = str01.find_first_of(str_lit01, 0, 3);
| > 
| > PGP Fingerprint: 
| > 0E2D D32A 8732 DC31 804C  D435 9BF0 F8FE 1C1B 9AD5
| > PGP Key at: http://i3.yimg.com/3/c7e5ee24/g/68fc2307.asc
| > 
| > -----BEGIN PGP SIGNATURE-----
| > Version: PGPfreeware 6.5.1 for non-commercial use < http://www.pgp.com >
| > Comment: PGP Key at: http://i3.yimg.com/3/c7e5ee24/g/68fc2307.asc
| > 
| > iQA/AwUBOT4oWJvw+P4cG5rVEQIoSQCeOSpeFs2Nop06UHzMjZkVjI6a+mkAnRIY
| > c7Xwm/ZImM9taKVPEJMj0MDt
| > =kN6L
| > -----END PGP SIGNATURE-----
| > 
| > 
| > 
| > __________________________________________________
| > Do You Yahoo!?
| > Talk to your friends online with Yahoo! Messenger.
| > http://im.yahoo.com
| > 
| > 

-- 
Damon Brent Verner
Cracker Jack® Certified Professional
brent@rcfile.org, brent@linux1.org


More information about the Libstdc++ mailing list