better code
better code
Posted May 29, 2003 22:20 UTC (Thu) by ncm (guest, #165)In reply to: strlcpy() by nas
Parent article: strlcpy()
I have posted a better implementation, also public domain.
Anyway I think it's better. You decide.
Posted May 30, 2003 4:15 UTC (Fri)
by tjc (guest, #137)
[Link]
Posted May 30, 2003 19:36 UTC (Fri)
by tjc (guest, #137)
[Link] (5 responses)
I haven't tested this extensively, but I've found that the best way to debug code is to post it on the internet. ;-) People come out of the woodwork...
Posted May 31, 2003 1:39 UTC (Sat)
by dododge (guest, #2870)
[Link] (3 responses)
Pointer comparison is undefined if the pointers
are not within the same object, so this is not
portable standard C.
I haven't looked closely at the rest of the function. If you
want it thoroughly picked apart you could try posting it to
USENET comp.lang.c [insert evil laugh]
Posted May 31, 2003 6:04 UTC (Sat)
by tjc (guest, #137)
[Link] (2 responses)
I've heard of this, but I have never read a good explanation. I just assumed that this restiction has something to do with pointer aliasing. If you understand this, now is the time to show off! ;-) memmove is safe for overlapping regions, and since it's part of the standard library it's allowed to use architecture-specific magic to compare arbitrary pointers. How is the performance of memmove()? Does it copy memory a double word at a time? I couldn't find a general way to do this without using architecture-specific magic as you say, so I fell back to memcpy(). BTW, s/int len, i/size_t len/ above. I noticed this about 100ns after I posted. Always use -Wall...
Posted Jun 2, 2003 6:13 UTC (Mon)
by eru (subscriber, #2753)
[Link]
I always assumed the restriction in the C standard exists mainly because
Posted Jun 4, 2003 3:39 UTC (Wed)
by dododge (guest, #2870)
[Link]
Well, it's undefined because the standard explicitly says so
Portability discussions come up in
Depends on your C library, compiler, operating
system, chip architecture, etc. You'll have to examine
your libc source to find out how it's done for your system. And
you'll also have to check your compiler output to make sure
it actually calls the libc implementation. For example gcc 2.95.3
on sparc-sun-solaris produces inline assembly for small
I'm rather fond of
Posted May 31, 2003 20:36 UTC (Sat)
by fjord (guest, #6510)
[Link]
http://sources.redhat.com/ml/libc-alpha/2000-08/msg00110.html strlcpy should return the size of the source string and do nothing, if the buffer is too small.
I timed both your implementation and Linus' through a 4 billion interation loop, and Linus has you by about 10 to 15 percent. But then he's using memcpy(), so there's an issue with overlapping source and destination strings..
better code
OK, here's my implementation:better code
size_t strlcpy(char *dest, const char *src, size_t n)
{
int len, i;
if (!n)
return 0;
len = strlen(src);
if (len >= n)
len = n - 1;
/* check for overlapping source and destination */
if ((src < dest && src + len >= dest)
|| (dest < src && dest + n > src)
|| src == dest)
{
size_t i;
for (i = 0; src[i] && i < n - 1; i++)
dest[i] = src[i];
dest[i] = (char) 0;
}
else
{
memcpy(dest, src, len);
dest[len] = (char) 0;
}
return len;
}
better code
/* check for overlapping source and destination */
if ((src < dest && src + len >= dest)
memmove
is safe for overlapping regions,
and since it's part of the standard library it's
allowed to use
architecture-specific magic to compare arbitrary
pointers. It can also make use of optimized machine
code, so it's potentially more efficient than any
implementation written in standard C.
but I've found that the best way to debug code is to post it on the internet.
:-)
Pointer comparison is undefined if the pointers are not within the same object, so this is not portable standard C.better code
>> Pointer comparison is undefined if the pointers are not within the samebetter code
>> object, so this is not portable standard C.
>
> I've heard of this, but I have never read a good explanation. I just
> assumed that this restiction has something to do with pointer aliasing. If
> you understand this, now is the time to show off! ;-)
in segmented memory management, the numeric values of pointers do not
necessarily correspond to their relative arrangement in memory.
Comparison is meaningful only for pointers that have the same segment
part. Since Linux does not use segmentation, at least not in an
user-visible way, there is no need to worry about this. (Few operating
systems use segments these days, but I happen to work with one that does,
even though it runs on the 32-bit versions of x86. Yes, 48-bit pointers!)
better code
Pointer comparison is undefined if the pointers are not within the same object,
I've heard of this, but I have never read a good explanation. I just assumed that this restiction has something to do with pointer aliasing.
:-)
. As to why the standard says so,
there is presumably some architecture out there that C works on
which cannot reliably support comparing arbitrary pointers; or
allowing this comparison might make it too difficult to implement
C on certain architectures. The most obvious reason for allowing
this would be to implement memmove
, which the standard
already provides.
comp.lang.c
fairly
often, and someone occasionally chimes in with an example of a real
architecture they deal with where common-sense assumptions about
computer architecture don't hold true.
There's a lot of weird designs out there, and when you start
talking about embedded devices they may even have a larger installed
base than anything x86-derived. The worst case is
the "DeathStation 9000", a hypothetical
machine where even the most subtle undefined
behavior produces catastrophic results.
How is the performance of memmove()? Does it copy memory a double word at a time?
memcpy
operations
rather than actually calling into libc.
Always use -Wall...
-ansi -pedantic -Wall -W
myself
:-)
Hmm, I haven't actually read the original documentation for the strl* functions, but according to this:better code