Branimir Maksimovic said:
Christian said:
Branimir Maksimovic wrote: [...]
Clearly memcpy parameter is not about number of copy operations, and
in this respect his conclusion is invalid, because if
memcpy(&x,&y,sizeof(x)-1) does not produce trap value,
implementation can use load register, store register,
Nope, you have to preseve the last byte.
What byte?
Implementation can do anything that does not change observable
behavior. Since you have stored something that is not
valid double object, last byte would not change observable behavior,
because using x as a double further in program
produces undefined behavior anyway.
Example:
double x, y;
x = 0.0; y = 1.0 / 3.0;
((unsigned char *) &x) [sizeof (x) - 1] = 79;
memcpy (&x, &y, sizeof (x) - 1);
how about original example with:
memcpy (&x, &y, sizeof (x));
if (((unsigned char *) &x) [sizeof (x) - 1] != 79)
printf ("This implementation is broken!\n");
I stored the number 79 into the last byte of x. The memcpy is not
allowed to overwrite it, so it must contain the value 79 after the call
to memcpy. There is no undefined behavior. There might be undefined
behavior if I _would_ use x as a double, but I don't, so there is no
undefined behavior.
Come on, this has completely different semantics then original example.
You have created valid unsigned char object at a given address
and dropped memcpy with sizeof(x). Stop playing around.
Ok, let's try again.
The code were were talking about has been buried several followups
upthread, but I think I've managed to find it:
double x, y;
memcpy (&x, &y, sizeof (x) - 1);
memcpy (&x, &y, sizeof (x));
I think each of the two memcpy() calls was intended to be considered
in isolation, not necessarily executed one after the other as implied
by the literal posted code. So let's ignore the second memcpy(), and
let's assume that sizeof(double) == 8 and CHAR_BIT==8.
The variable x is an 8-byte object. When viewed as a double, it's
uninitialized, so any attempt to access its value invokes undefined
behavior. But when viewed as an array of unsigned char, it's a
sequence of 8 elements, each of which has some value in the range
0..255 (though what those values are is, of course, indeterminate).
The same is true for y.
The statement
memcpy(&x, &y, sizeof(x)-1);
copies the first 7 bytes of y into the first 7 bytes of x. The 8th
byte of x is untouched. If the program prints the value of the 8th
byte before and after the memcpy(), it must print the same value both
times; if it doesn't, the implementation is broken.