Is it legal to use memcpy with a persistent member target structure?

For example, the following function is valid:

struct two_int { const int a, b; } void copy_two(const two_int *src, two_int *dest) { memcpy(dest, src, sizeof(two_int)); } 

It seems that at least some types of modifications of constant-defined values ​​are unacceptable, but it is not clear to me if this is consistent.

If the answer is “ not allowed, in the general case”, I’m also interested to know about the special case when dest is the new allocated memory with malloc (and therefore hasn’t got any value yet), for example:

 two_int s = {.a = 1, .b = 2}; two_int *d = malloc(sizeof(two_int)); copy_two(&s, d); 

Update: The last question seems to have answered in the affirmative (this is OK) for the case of the new malloc structure, but the original, more general question still stands, I think.

+5
source share
1 answer

Using memcpy for such purposes will only determine behavior if the actual destination does not have a static or automatic duration.

Based on the code:

 struct foo { double const x; }; void outsideFunction(struct foo *p); double test(void) { struct foo s1 = {0.12345678}; outsideFunction(&s1); return 0.12345678; } 

the compiler will have the right to optimize the function:

 double test(void) { static struct foo const s1 = {0.12345678}; outsideFunction(&s1); return s1.x; } 

On many processors, the only way to load double with an arbitrary constant is to load its value from an object containing this constant, in which case the compiler will conveniently know the object (s1.x), which should contain the constant 0.12345678. The net effect would be that the code that memcpy used to write to s1.x could ruin other uses of the numerical constant 0.12345678. As the saying goes, "there will be no variables, no constants." Unpleasant stuff.

The problem will not exist for objects with a designated duration, because memcpy requires that the compiler “forget” everything about what was previously stored in the destination repository, including any “efficient type”. Declared types of static and automatic objects exist regardless of what is stored in them, and cannot be deleted using "memcpy" or any other means, but objects with a limited validity period have only an "effective type" that will be deleted.

0
source

Source: https://habr.com/ru/post/1264109/


All Articles