Liste des Groupes | Revenir à c arch |
On Mon, 9 Sep 2024 10:20:00 +0200That's my experience too, but as you say, it is compiler (and flag) dependent.
Terje Mathisen <terje.mathisen@tmsw.no> wrote:
Tim Rentsch wrote:In simple situations like shown above, memmove is as dependable asmitchalsup@aol.com (MitchAlsup1) writes:>
On Wed, 4 Sep 2024 17:53:13 +0000, David Brown wrote:>
On 04/09/2024 18:07, Tim Rentsch wrote:
Terje Mathisen <terje.mathisen@tmsw.no> writes:>
Michael S wrote:>
On Tue, 3 Sep 2024 17:41:40 +0200>
Terje Mathisen <terje.mathisen@tmsw.no> wrote:
Michael S wrote:>
3 years ago Terje Mathisen wrote that many years ago he read>
that behaviour of memcpy() with overlappped src/dst was
defined.
https://groups.google.com/g/comp.arch/c/rSk8c7Urd_Y/m/ZWEG5V1KAQAJ
Mitch Alsup answered "That was true in 1983". So, two
people of different age living in different parts of the
world are telling the same story. May be, there exist old
popular book that said that it was defined?
It probably wasn't written in the official C standard, which I
couldn't have afforded to buy/read, but in a compiler runtime
doc?
>
Specifying that it would always copy from beginning to end of
the source buffer, in increasing address order meant that it
was guaranteed safe when used to compact buffers.
What is "compact buffers" ?
Assume a buffer consisting of records of some type, some of
them marked as deleted. Iterating over them while removing
the gaps means that you are always copying to a destination
lower in memory, right?
If all the records are in one large array, there is a simple
test to see if memcpy() must work or whether some alternative
should be used instead.
Such tests are usually built into implementations of memmove(),
which will chose to run forwards or backwards as needed. So you
might as well just call memmove() any time you are not sure
memcpy() is safe and appropriate.
The ever-shallow David Brown first misses the point, then makes a
slightly incorrect statement, and finally makes a recommendation
that surely is familiar to every reader in the newsgroup.
Memmove() is always appropriate unless you are doing something>
nefarious.
>
So:
# define memcpy memomve
Incidentally, if one wants to do this, it's advisable to write
>
#undef memcpy
>
before the #define of memcpy.
What really worries me is that I've been told (and shown in godbolt)
that memcpy() can be magic, i.e the ocmpiler is allowed to make it
NOP when I use it to move data between an integer and float variable:
>
float invsqrt(float x)
{
...
int32_t ix = *(int32_t *) &x;
>
is deprecated, instead do something like this:
>
int32_t ix;
memcpy(&ix, &x, sizeof(ix));
>
and the compiler will see that x and ix can share the same register.
>
I don't suppose memmove() can be dependent upon to do the same?
>
Terje
>
memcpy.
I don't know if it is always true in more complex cases, where absence
of aliasing is less obvious to compiler. However, I'd expect that as
long as a copied item fits in register, the magic will work equally
with both memcpy and memmove.
It depends on compiler, too.
MSVC from VS2019 produces the same code for both variants d_to_u below.
But MSVC from VS2017 does not.
#include <stdint.h>
#include <string.h>
void d_to_u_cpy(uint64_t* u, const double* d) {
memcpy(u, d, sizeof(*u));
}
#define memcpy memmove
void d_to_u_move(uint64_t* u, const double* d) {
memcpy(u, d, sizeof(*u));
}
Les messages affichés proviennent d'usenet.