Heh - there's a question :). Looking at the two implementations, which do you think you better understand (with complete certainty), and which would you be willing to (say) bet your life on?
Personally I'm *almost* certain I know what the first does :). I would not want to bet it is bug-free. I'm sure the shorter implementation matches the *documented* strlcat() function. The fact it runs faster is likely an artifact of compiler optimizations specific to string functions. I'll send this off to the OpenBSD folks just for grins. From: Andi Gutmans [mailto:[EMAIL PROTECTED]] > Are you sure it behaves *exactly* like the existing one? > I stole the implementation from OpenBSD so it might be a good idea for you > to send it to them. > They are the best to shed light on this and see if it's exactly the same > and faster. > > Andi > > At 09:00 02/05/2002 -0700, Preston L. Bannister wrote: > >Was looking at the strlcat() implementation in the PHP source > >and saw that it does not take advantage of history :). > > > >Look at xxx_strlcat() in the following example. > > > >You are almost always better off using the compiler's built-in > >string functions, due to the optimizations built-in (many years ago) > >to improve Dhrystone benchmark scores. The benchmark turned out to > >be a bit bogus, but the improvements made to the string functions > >are a benefit to us all :). > > > >This is more readable (and thus more likely correct), slightly faster > >(about 4% in my testing), and in the debug build better checked. > > > >Full comparison benchmark program: > >----- > >#include <stdlib.h> > >#include <stdio.h> > >#include <string.h> > >#include <time.h> > >#include <assert.h> > > > >/* > > * Appends src to string dst of size siz (unlike strncat, siz is the > > * full size of dst, not space left). At most siz-1 characters > > * will be copied. Always NUL terminates (unless siz == 0). > > * Returns strlen(src); if retval >= siz, truncation occurred. > > */ > >size_t php_strlcat(char* dst,const char* src,size_t siz) > >{ > > register char *d = dst; > > register const char *s = src; > > register size_t n = siz; > > size_t dlen; > > > > /* Find the end of dst and adjust bytes left but don't go past end */ > > while (*d != '\0' && n-- != 0) > > d++; > > dlen = d - dst; > > n = siz - dlen; > > > > if (n == 0) > > return(dlen + strlen(s)); > > while (*s != '\0') { > > if (n != 1) { > > *d++ = *s; > > n--; > > } > > s++; > > } > > *d = '\0'; > > > > return(dlen + (s - src)); /* count does not include NUL */ > >} > > > >/* > > * Take full advantage of any compiler/library optimizations built in > > * to the standard string routines. Look up the history of compiler > > * comparisons with Dhrystone benchmark to understand why this wins. > > * Pre-Internet history - check Google's USENET archive. > > */ > >size_t xxx_strlcat(char* s1,const char* s2,size_t nMax) > >{ > > size_t n1 = strlen(s1); > > size_t n2 = strlen(s2); > > size_t nCopy = (nMax <= (n1+n2)) ? (nMax - n1 - 1) : n2; > > > > /* Better to leave this out and require a valid string return */ > > if (!nMax) return 0; > > > > assert(n1 < nMax); /* Catch pre-existing oversize strings */ > > assert(0 < nMax); /* Insure return is always a valid string */ > > > > memcpy(s1+n1,s2,nCopy); > > s1[n1+nCopy] = 0; > > return n1+n2; /* as documented for strlcat() */ > > /*return n1+nCopy; /* actual number of characters */ > >} > > > >/* > > * > > */ > >int main(int ac, char** av) > >{ > > clock_t t1,dt; > >#ifdef WIN32 > > __int64 nTotal; > >#else > > long long nTotal; > >#endif > > char s1[85]; > > static char s2[] = "1234567890"; > > int nLoops = 10; > > > > if (1 < ac) { > > nLoops = atoi(av[1]); > > } > > > > printf("Compare two strlcat() implementations for %d > > iterations.\n",nLoops); > > > > t1 = clock(); > > nTotal = 0; > > for (int i=0; i<nLoops; ++i) { > > s1[0] = 0; > > nTotal += php_strlcat(s1,s2,sizeof(s1)); > > nTotal += php_strlcat(s1,s2,sizeof(s1)); > > nTotal += php_strlcat(s1,s2,sizeof(s1)); > > nTotal += php_strlcat(s1,s2,sizeof(s1)); > > nTotal += php_strlcat(s1,s2,sizeof(s1)); > > nTotal += php_strlcat(s1,s2,sizeof(s1)); > > nTotal += php_strlcat(s1,s2,sizeof(s1)); > > nTotal += php_strlcat(s1,s2,sizeof(s1)); > > nTotal += php_strlcat(s1,s2,sizeof(s1)); > > nTotal += php_strlcat(s1,s2,sizeof(s1)); > > } > > dt = clock() - t1; > > > > printf("php_strlcat() copied %1.0f characters in %ld > > ticks\n",(double)nTotal,(long)dt); > > > > t1 = clock(); > > nTotal = 0; > > for (i=0; i<nLoops; ++i) { > > s1[0] = 0; > > nTotal += xxx_strlcat(s1,s2,sizeof(s1)); > > nTotal += xxx_strlcat(s1,s2,sizeof(s1)); > > nTotal += xxx_strlcat(s1,s2,sizeof(s1)); > > nTotal += xxx_strlcat(s1,s2,sizeof(s1)); > > nTotal += xxx_strlcat(s1,s2,sizeof(s1)); > > nTotal += xxx_strlcat(s1,s2,sizeof(s1)); > > nTotal += xxx_strlcat(s1,s2,sizeof(s1)); > > nTotal += xxx_strlcat(s1,s2,sizeof(s1)); > > nTotal += xxx_strlcat(s1,s2,sizeof(s1)); > > nTotal += xxx_strlcat(s1,s2,sizeof(s1)); > > } > > dt = clock() - t1; > > > > printf("xxx_strlcat() copied %1.0f characters in %ld > > ticks\n",(double)nTotal,(long)dt); > > > > return 0; > >} > >----- -- PHP Development Mailing List <http://www.php.net/> To unsubscribe, visit: http://www.php.net/unsub.php