以下在 C 中安全吗?
struct Buffer {
size_t size;
int8_t *storage;
};
struct Context {
struct Buffer buffer;
int8_t my_storage[10];
};
struct Context my_context = {
.buffer = {
.size = 0,
.storage = my_context.my_storage,
},
.my_storage = {0},
};
我正在使用微 Controller ,我不想必须使用 malloc。此外,对我来说,收集结构中的所有内容比将存储作为上下文外部的单独变量更好。
[编辑1]
我已经测试过它并且它可以编译和工作,因为指向 my_context.my_storage
和 my_context.buffer.storage
的指针是相同的,gcc (Debian 4.7 .2-5)
Linux 上的 4.7.2
... 3.2.0-4-amd64 #1 SMP Debian 3.2.65-1+deb7u2 x86_64 GNU/Linux
[编辑2] 在后来被删除的答案中,我提到了 C99 标准第 6.7.8-19 节“初始化应按初始化列表顺序进行......”这是否意味着
struct Context my_context = {
.my_storage = {0},
.buffer = {
.size = 0,
.storage = my_context.my_storage,
},
};
能保证安全吗?我是这样理解的。
[编辑3] 下面是一个完整的工作示例。
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
struct Buffer {
size_t size;
int8_t *storage;
};
struct Context {
struct Buffer buffer;
int8_t my_storage[10];
};
struct Context my_context = {
.buffer = {
.size = 0,
.storage = my_context.my_storage,
},
.my_storage = {0},
};
int
main(void)
{
printf ("ptr points to: %" PRIXPTR "\n", (uintptr_t)my_context.buffer.storage);
printf ("storage is at: %" PRIXPTR "\n", (uintptr_t)my_context.my_storage);
}
>> ./test
ptr points to: 600950
storage is at: 600950
最佳答案
是的,这很好。假设 my_context
有自动存储持续时间,它的生命周期从进入关联 block 开始,并且在它的生命周期中它有一个常量地址(6.2.4 对象的存储持续时间/2 ). (如果它具有静态或线程存储持续时间,则其生命周期分别延长整个程序或线程的持续时间)。
由此可见,my_context.my_storage
在 my_context
的生命周期内也有一个常量地址,因此将其地址(通过数组到指针衰减)用于初始化my_context.buffer.storage
将给出与 my_context
初始化完成后相同的值。
另请注意,my_context
的范围从其声明完成的点开始,即在初始化程序的 =
之前,因此在其初始化程序中引用它也可以。
关于c - 将成员地址分配给结构中的其他成员,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30162131/