scs@athena.mit.edu (Steve Summit) (09/13/88)
In article <8389@smoke.ARPA> gwyn@brl.arpa (Doug Gwyn) writes: >Some implementations of bcopy() and memcpy() do guarantee >proper handling of overlapping fields. But not all do, so one cannot >count on it if one's trying to write truly portable code. ANSI C will >specify a new function memmove() with this property guaranteed. I'll probably be disgusted by the answer, but can someone explain why two functions are needed instead of one? Why not just add the guarantee to memcpy? In my experience, it's not hard to implement the correct, bidirectional copy behavior. Did someone actually manage to convince the committee that there is an architecture and/or implementer out there that is so badly broken that the overlap test would significantly slow down programs which did not need the guarantee? Or is it a code size issue for potential in-line implementations? (I am aware that a correct overlap test is not trivial for badly broken architectures such as the segmented 80x86, but the correct test on those machines is not really hard or slow, either.) Steve Summit scs@adam.pika.mit.edu
gwyn@smoke.ARPA (Doug Gwyn ) (09/13/88)
In article <7039@bloom-beacon.MIT.EDU> scs@adam.pika.mit.edu (Steve Summit) writes: >I'll probably be disgusted by the answer, but can someone explain >why two functions are needed instead of one? Why not just add >the guarantee to memcpy? (1) many people want a fast block-move, many want one that does the "correct" thing on overlaps. Two routines allows the application to choose the trade-off. A vendor could choose to make memcpy just another entry point for memmove. (2) it's possible that some existing (nonportable) applications depend on the specific implementation of their current memcpy().
mmengel@cuuxb.ATT.COM (~XT4103000~Marc Mengel~C25~G25~6184~) (09/14/88)
In article <7039@bloom-beacon.MIT.EDU> scs@adam.pika.mit.edu (Steve Summit) writes: >In article <8389@smoke.ARPA> gwyn@brl.arpa (Doug Gwyn) writes: >>Some implementations of bcopy() and memcpy() do guarantee >>proper handling of overlapping fields. But not all do, so one cannot >>count on it if one's trying to write truly portable code. ANSI C will >>specify a new function memmove() with this property guaranteed. > >I'll probably be disgusted by the answer, but can someone explain >why two functions are needed instead of one? Why not just add >the guarantee to memcpy? > Steve Summit To check whether the source and destination overlap, you have to compare two pointer values. You can only do this legally ($3.3.8) if the two pointers point into the same array/aggregate. Hence you need memmove() for shifting items in an array, and memcpy() for moving items between arrays. Using memmove() on items not in the same array is therefore not guaranteed to work, as the comparison of pointers not in the same array/aggregate is undefined. The issue is that to make memcpy() work the way you want it to, you need to define pointer semantics for comparison on pointers that don't point into the same array/aggregate. Feel free to post a definition for these semantics, I am sure the various net.hackers out there can name you a machine that your semantics don't make sense on; or force pointers to be unusually large objects. -- Marc Mengel mmengel@cuuxb.att.com attmail!mmengel {lll-crg|mtune|att}!cuuxb!mmengel
scjones@sdrc.UUCP (Larry Jones) (09/14/88)
In article <7039@bloom-beacon.MIT.EDU>, scs@athena.mit.edu (Steve Summit) writes: > I'll probably be disgusted by the answer, but can someone explain > why two functions are needed instead of one? Why not just add > the guarantee to memcpy? In my experience, it's not hard to > implement the correct, bidirectional copy behavior. Did someone > actually manage to convince the committee that there is an > architecture and/or implementer out there that is so badly broken > that the overlap test would significantly slow down programs > which did not need the guarantee? Or is it a code size issue for > potential in-line implementations? (I am aware that a correct > overlap test is not trivial for badly broken architectures such > as the segmented 80x86, but the correct test on those machines is > not really hard or slow, either.) All of the above. Many machines have only a single block move instruction which means that the "backwards" move has to be very inefficient and you need to do a true overlap test (rather than a simple direction test). That could add up to a lot of code to inline, but it would really hurt to not inline if the overlap case never happens. The easiest way for the compiler to know for sure whether the overlap case ever happens is to have different functions for the different cases. Also, the committee received a number of letters noting that there are some fairly common operations where memcpy is the inner loop and so ANY slowdown would be unacceptable (e.g. block moves on bitmap displays). ---- Larry Jones UUCP: uunet!sdrc!scjones SDRC scjones@sdrc.uucp 2000 Eastman Dr. BIX: ltl Milford, OH 45150 AT&T: (513) 576-2070 "Save the Quayles" - Mark Russell
henry@utzoo.uucp (Henry Spencer) (09/14/88)
In article <7039@bloom-beacon.MIT.EDU> scs@adam.pika.mit.edu (Steve Summit) writes: >I'll probably be disgusted by the answer, but can someone explain >why two functions are needed instead of one? Why not just add >the guarantee to memcpy? ... The key observation is that in many cases the programmer knows that the source and destination do not overlap, and it is difficult for the compiler to figure this out except by checking it at run time. This is particularly significant if the compiler is doing inlining for efficiency and relatively small amounts of data are being moved -- in such a case, the overlap check may significantly hurt performance. Since the older definitions of memcpy explicitly said "if the operands overlap, no guarantees", it seemed sound to make memcpy the fast-but-dangerous case and add a new function for the slow-but-safe case. -- NASA is into artificial | Henry Spencer at U of Toronto Zoology stupidity. - Jerry Pournelle | uunet!attcan!utzoo!henry henry@zoo.toronto.edu
karl@haddock.ima.isc.com (Karl Heuer) (09/14/88)
In article <2063@cuuxb.ATT.COM> mmengel@cuuxb.ATT.COM (Marc Mengel) writes: >To check whether the source and destination overlap, you have to compare two >pointer values. You can only do this legally ($3.3.8) if the two pointers >point into the same array/aggregate. Watch it -- the first `you' refers to the implementation; the second refers to the user. Certainly the implementation is free to generate any code that happens to work. >Hence you need memmove() for shifting items in an array, and memcpy() for >moving items between arrays. Using memmove() on items not in the same array >is therefore not guaranteed to work, as the comparison of pointers not in the >same array/aggregate is undefined. No, memmove() is guaranteed to work on *any* valid pointers. What you've really proved is that memmove() cannot be portably implemented in C. Karl W. Z. Heuer (ima!haddock!karl or karl@haddock.isc.com), The Walking Lint Followups to comp.std.c.
henry@utzoo.uucp (Henry Spencer) (09/15/88)
In article <2063@cuuxb.ATT.COM> mmengel@cuuxb.UUCP (Marc W. Mengel) writes: >The issue is that to make memcpy() work the way you want it to, you >need to define pointer semantics for comparison on pointers that don't >point into the same array/aggregate... This is largely irrelevant, since the insides of memcpy will usually be highly machine-specific anyway. -- NASA is into artificial | Henry Spencer at U of Toronto Zoology stupidity. - Jerry Pournelle | uunet!attcan!utzoo!henry henry@zoo.toronto.edu