我有一个复杂的数据结构(有很多不完整的数组类型/异构长度的结构数组和指向结构数组的结构指针......)
我想把它们放在闪存中,所以我考虑将它们放在静态存储的 const 对象中(它们将存储在闪存中),让编译器完成它的工作。
我在嵌入式环境中工作,其中 ROM==flash==data 我无法进行物理更改。我的 RAM 很少,当然也不足以存储我所有的数据。可以告诉 GCC 毫无问题地将静态常量数据存储到 ROM。
数据不能动态构造,因为它应该保留在闪存中。
我目前正在使用 C(不是 C++)和 4.8 gcc,并且不介意使用 GCCisms。
但是我不断遇到错误消息,例如:
- 初始化元素不是常量
- 不兼容的指针类型
- ...
与最近的不同 gcc 版本不同,表明此功能(混合复合文字、指定的初始化器、...)是最近的或不是主线。
请注意,此代码是由程序(脚本)生成的。
除了我不断犯的错误(我可以更具体并在那里寻求帮助),你会建议什么策略:
- 继续尝试使用复合文字来使用复杂的嵌套文字结构
- 具有大量类型的复合文字
- 具有多个相互指向的复合文字类型
- 用他们的名字构建许多中间对象(使整个事情变得非常不可读)
构建一个大的 uint32_t datablob[] 并适本地转换我的结构(额外的是无法在对象之间存储指针,因为我的链接器将指定这将在何处结束)
还有其他选择吗?
(编辑:添加细节)
好吧,我的问题更多是关于通用策略,但这里有一个例子:
struct A
{
int id;
int codes[];
};
struct B
{
int b_member;
struct A *a[]; // array of ptr to A objects
};
struct C
{
int c_member;
struct B *objects[]; // array of ptrs on B
};
const struct A rom_data = { .id=4, .codes = {1,2,3,4}}; // this is in ROM
int main(void) {}
我想像为 A 所做的那样声明一个 C 结构数组。 (这意味着我不想复制数据、从磁盘读取数据或对其进行 malloc,只需声明一个包含数据的 const。)
我所有关于文字的例子都非常简单。
我的平台的细节是一个 ARM 微 Controller ,但考虑到我想声明一个 const。
最佳答案
您应该使用 const
限定的指针而不是灵活的数组成员。
有一些示例代码:
#include <stddef.h>
struct A
{
int id;
const int *codes;
};
struct B
{
int b_member;
const struct A *const *a;
};
struct C
{
int c_member;
const struct B *const *objects;
};
static const struct C ROOT = { 0, (const struct B *[]){
&(const struct B){ 0, (const struct A *[]){
&(const struct A){ 0, (const int []){ 1, 2, 3 } },
&(const struct A){ 1, (const int []){ 0 } },
} },
&(const struct B){ 42, NULL },
} };
如评论中所述,似乎没有必要通过指针引用结构。这简化了代码:
#include <stddef.h>
struct A
{
int id;
const int *codes;
};
struct B
{
int b_member;
const struct A *a;
};
struct C
{
int c_member;
const struct B *objects;
};
static const struct C ROOT = { 0, (const struct B []){
{ 0, (const struct A []){
{ 0, (const int []){ 1, 2, 3 } },
{ 1, (const int []){ 0 } },
} },
{ 42, NULL },
} };
如果您想要或需要 C90 兼容性,您可以展平树并让生成脚本跟踪相应数组中的偏移量:
static const int ARRAY_OF_INT[] = {
1, 2, 3,
0,
};
static const struct A ARRAY_OF_A[] = {
{ 0, ARRAY_OF_INT + 0 },
{ 1, ARRAY_OF_INT + 3 },
};
static const struct B ARRAY_OF_B[] = {
{ 0, ARRAY_OF_A + 0 },
{ 42, NULL },
};
static const struct C ROOT = { 0, ARRAY_OF_B + 0 };
关于c - 声明复杂 C 结构化常量数据的策略?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25652918/