(though I believe the compiler only calls memcpy and makes sure there is no overlap)
I haven't explored all the cases where the compiler generates these calls, but a suggest a slightly different approach:
Implement the memory copy loop in two different functions, one that does the loop in increasing addresses, and the other in decreasing addresses. memcpy() can always call the first one. memmove() uses the increasing address one if source address is above the destination address, and the decreasing address one if source address is below the destination address.
That's not a different approach, it's the same approach.
Okay. I guess I got hung up on the mention of same function and avoid overlap, since I use a pair of functions that differ only in the loop direction.
Except memcpy() should be whichever of increasing or decreasing addresses is the fastest, and memmove() either uses the slower one or tail-calls memcpy when it can. Often a decreasing loop is the fastest.
True.
You *could* if code space is really really tight have memset() poke the constant into the first/last bytes of the memory range and then call memcpy() with an overlapping range. However this is a pretty slow way to implement memset(), and probably setting up the call to memcpy() is just as much code as the (twice as fast) loop to just write the same data from a register repeatedly. False savings.
Fully agreed.
(While memrepeat() does exactly that, it is only useful when the data to be filled is composite, a structure or union, or possibly a floating-point value on architectures without floating-point registers, and larger than a machine register in size. memset() is easily implemented more efficiently than that, and is common enough to spend the dozen or two bytes for its implementation.)
Even things like checking whether the range is aligned or not, and doing the loop using native word size elements (with the fill byte duplicated across the bytes in that word) is not usually worth it at run time, generally speaking, for any of these functions. Using C11 _Alignof (or the earlier GCC/clang/ICC
__alignof__ operator) one can create an inline wrapper that can select between an optimized (native word alignment and size) or a byte-per-byte version, which may be useful on some architectures; but then that wrapper is visible in the header file and linkage won't be to memset()/memcpy()/memmove()/memcmp() but to the optimized or per-byte version instead.
Basically this IDE stuff is a tool which got put together by real men, for real men
for Homo real Neanderthalensis beings for real Neanderthals, you mean.
Dude, some of my distant ancestors were Neanderthals, and they had bigger brains than we do. The ooga-booga-cavemen is a poor stereotype. Get an expert in them drunk, and they'll admit that everything points out to them having been more intelligent than us –– heck, that people who lived a few thousand years ago were not only more intelligent than us but also with bodies closer to olympic athletes than the potato sacks we are ––, which itself is sufficient incentive for most humans to paint them ugly.
If you exclude childhood deaths, even their life expectancy was similar to ours, and much longer than most humans during the agricultural era. Yes, they had hard lives in that most male skeletons found show signs of old fractures having fully healed, but that also shows that such injuries were dealt with and not fatal.