Liste des Groupes | Revenir à c arch |
Tim Rentsch <tr.17687@z991.linuxsc.com> writes:
>anton@mips.complang.tuwien.ac.at (Anton Ertl) writes:>
>
[considering which way to copy with memmove()]
>If the two memory blocks don't overlap, memmove() can use the
fastest stride. [...]
>
The way to go for memmove() is:
>
On hardware where positive stride is faster:
>
if (((uintptr)(dest-src)) >= len)
return memcpy_posstride(dest,src,len)
else
return memcpy_negstride(dest,src,len)
>
On hardware where the negative stride is faster:
>
if (((uintptr)(src-dest)) >= len)
return memcpy_negstride(dest,src,len)
else
return memcpy_posstride(dest,src,len)
>
And I expect that my test is undefined behaviour, but most people
except the UB advocates should understand what I mean.
...
>Last but not least, having two different code blocks for the>
different preferences is clunky. The two blocks can be
combined by fusing the two test expressions into a single
expression, as for example
>
#ifndef PREFER_UPWARDS
#define PREFER_UPWARDS 1
#endif/*PREFER_UPWARDS*/
>
extern void* ascending_copy( void*, const void*, size_t );
extern void* descending_copy( void*, const void*, size_t );
>
void *
good_memmove( void *vd, const void *vs, size_t n ){
const char *d = vd;
const char *s = vs;
_Bool upwards = PREFER_UPWARDS ? d-s +0ull >= n : s-d +0ull < n;
>
return
upwards
? ascending_copy( vd, vs, n )
: descending_copy( vd, vs, n );
}
>
Using the preprocessor symbol PREFER_UPWARDS to select between
the two preferences (ascending or descending) allows the choice
to made by a -D compiler option, and we can expect the compiler
to optimize away the part of the test that is never used.
That's clever, but for usage in glibc or the like the clunky version
is the preferred one: [elaboration]
Les messages affichés proviennent d'usenet.