LWN.net Logo

better code

better code

Posted May 31, 2003 1:39 UTC (Sat) by dododge (subscriber, #2870)
In reply to: better code by tjc
Parent article: strlcpy()


/* check for overlapping source and destination */
if ((src < dest && src + len >= dest)

Pointer comparison is undefined if the pointers are not within the same object, so this is not portable standard C.

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.

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] :-)


(Log in to post comments)

better code

Posted May 31, 2003 6:04 UTC (Sat) by tjc (guest, #137) [Link]

Pointer comparison is undefined if the pointers are not within the same 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! ;-)

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...

better code

Posted Jun 2, 2003 6:13 UTC (Mon) by eru (subscriber, #2753) [Link]

>> Pointer comparison is undefined if the pointers are not within the same
>> 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! ;-)

I always assumed the restriction in the C standard exists mainly because
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

Posted Jun 4, 2003 3:39 UTC (Wed) by dododge (subscriber, #2870) [Link]

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.

Well, it's undefined because the standard explicitly says so :-). 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.

Portability discussions come up in 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?

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 memcpy operations rather than actually calling into libc.

Always use -Wall...

I'm rather fond of -ansi -pedantic -Wall -W myself :-)

Copyright © 2012, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds