Path: utzoo!utgpu!water!watmath!clyde!rutgers!ames!think!husc6!bbn!uwmcsd1!ig!agate!ucbvax!hplabs!oracle!rbradbur From: rbradbur@oracle.UUCP (Robert Bradbury) Newsgroups: comp.sys.ibm.pc Subject: Re: bug in Turbo C 1.5 Summary: Why both memcmp/memmove and non-portability of str/memcmp() Keywords: memcmp, memmove, strcmp, memcmp, Borland C Message-ID: <241@oracle.UUCP> Date: 13 Feb 88 21:44:56 GMT References: <5331@cit-vax.Caltech.Edu> Reply-To: rbradbur@oracle.UUCP (Robert Bradbury) Distribution: comp.sys.ibm.pc,comp.lang.c Organization: Oracle Corporation, Belmont, CA Lines: 61 In article <5331@cit-vax.Caltech.Edu> tim@cit-vax.UUCP (Timothy L. Kay) writes: > >I'd like to make two points. First, why was it necessary for Borland >to *change* memcpy to conform to the standard? It seems to me that the >old version of memcpy already conformed to the standard. In changing >memcpy, they only caused people like me inconvenience. (Please don't >suggest that some people want to use memcpy to clear memory.) Ah, a question I can answer finally :-). As one of the prime motivators of the addition of memmove() to the standard I can explain the reasons for this. The problem revolves around trying to serve 2 masters in the C runtime library: efficiency and portability. The original (to the best of my knowledge) definition for memcpy() (Unix System V memory(3C)) is: "memcpy copies *n* characters from memory area *s2* to *s1*". It is undefined what happens if the memory areas overlap. On the VAX memcpy() was implemented using movc3/c5 instructions which have clever microcode which handles overlapping copies correctly. On a variety of other machines implementors had less smart instructions and chose to implement memcpy() efficiently using instructions which did not handle overlapping areas. This gets particularly important as compiler vendors are now providing in-line versions of memcpy() which *usually* do not handle overlapping copies. (Supporting overlapping copies involves adding extra code on most machines.) We (at Oracle) build large DBMS which run on a variety of machines and desire that functions which move bytes of data around should be both efficient AND portable. In order to have efficient in-line functions we recommended the C standard support memcpy() as not having to handle overlapping copies. To handle copies of overlapping areas portably (and efficiently on machines with clever microcode) the function memmove() was added. Borland simply changed memcpy to be the more efficient implementation allowed by the current draft of the C standard. I'll admit we could have gone the other way on the names (adding memecpy() for efficient copies) but it was felt that the majority of current memcpy() uses did not involve overlapping copies so "standardizing" the existing practice of machines where memcpy() did not handle overlapping copies would not break alot of code on those machines where memcpy() did handle overlapping copies. Most people have no idea of the effort which goes into standardizing something like C. Suffice to say that when something is done there are usually good reasons behind it and that in many cases the compromises required are going to upset someone. On another note; does everyone realize that the current standard allows the results of the str/memcmp() function to be implementation defined if the characters being compared have the high-bit set? The net result is to prevent portable comparisons of unsigned chars or European/EBCDIC character sets. This has been pointed out to the committee but they didn't feel it was "significant". So if you are writing portable code and plan to compare anything other than standard ASCII text you should define your own comparison functions and not rely on the runtime library. -- Robert Bradbury Oracle Corporation (206) 784-9726 hplabs!oracle!rbradbur