例如,以下功能是合法的:
struct two_int {
const int a, b;
}
void copy_two(const two_int *src, two_int *dest) {
memcpy(dest, src, sizeof(two_int));
}
似乎至少某些类型的常量定义值的修改是不允许的,但我不清楚这是否符合条件。
如果答案是“一般情况下不允许”,我也想知道dest
是malloc
新分配的内存的特殊情况({1}}(因此尚未被赋予任何价值),例如:
two_int s = {.a = 1, .b = 2};
two_int *d = malloc(sizeof(two_int));
copy_two(&s, d);
更新:对于新malloc
'd结构的情况,似乎后一个问题似乎得到肯定(可以)回答,但是原始的,更一般的问题我认为仍然有效。
答案 0 :(得分:0)
仅当实际目标对象没有静态或自动持续时间时,才会将memcpy
用于此类目的。
鉴于代码:
struct foo { double const x; };
void outsideFunction(struct foo *p);
double test(void)
{
struct foo s1 = {0.12345678};
outsideFunction(&s1);
return 0.12345678;
}
编译器有权优化函数:
double test(void)
{
static struct foo const s1 = {0.12345678};
outsideFunction(&s1);
return s1.x;
}
在许多处理器上,加载具有任意常量的double的唯一方法是从保持该常量的对象加载其值,在这种情况下,编译器将方便地知道必须保持常量的对象(s1.x) 0.12345678。最终结果是使用memcpy
写入s1.x
的代码可能会破坏数字常量0.12345678的其他用法。俗话说“变量不会;常数不会”。讨厌的东西。
对于分配持续时间的对象,问题不存在,因为memcpy要求编译器“忘记”目前存储中先前存储的所有内容,包括任何“有效类型”。声明的静态和自动对象的类型独立于存储在其中的任何内容,并且不能通过“memcpy”或任何其他方式擦除,但是分配持续时间对象仅具有将被擦除的“有效类型”。