This is the mail archive of the newlib@sourceware.org mailing list for the newlib project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] add memrchr(3)


On 05/09/2012 12:42 PM, Gregory Pietsch wrote:
> I have been thinking of how many crazy ways there are to implement
> memrchr as a result of this discussion.
> 
> First, the usual way:
> 
> #include<string.h>
>  /* memrchr */
>  void  *(memrchr)(const  void  *s,  int  c,  size_t  n)
>  {
>      const  unsigned  char  *src=  s;
>      unsigned  char  uc=  c;
> 
>      src += n - 1;
>       while  (src  >=  (const unsigned char *) s)  {
>          if  (*src==  uc)
>              return  (void  *)  src;
>          --src;
>      }
>      return  NULL;
>  }

Probably good enough, if that's the way BSD did it (but in that case,
copy the BSD file as a reference implementation).

> 
> 
> I was also thinking recursion. Maybe that would be faster:
> 
> #include<string.h>
>  /* memrchr */
>  void  *(memrchr)(const  void  *s,  int  c,  size_t  n)
>  {
>      const  unsigned  char  *src=  s;
>      unsigned  char  uc=  c;
> 
>      return n ? (src[n - 1] == uc ? (void *) (src + n - 1)
>        : memrchr (s, c, n - 1)) : 0;

No.  Unless the compiler optimizes the tail-recursion out, this is
slower, and risks overflowing the user's stack when handed malicious
data.  Never a good idea to use recursion in libc, when iteration will do.

-- 
Eric Blake   eblake@redhat.com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org

Attachment: signature.asc
Description: OpenPGP digital signature


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]