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