【问题标题】:Initialize struct with macro用宏初始化结构
【发布时间】:2019-10-25 12:47:35
【问题描述】:

我有这个结构

typedef struct {
    int Length;
    int Data[];
} MyStruct;

还有这个宏来初始化结构体

#define FillStruct(...)     { .Length = sizeof((int[]){__VA_ARGS__}), .Data = {__VA_ARGS__} }

所以我可以用

初始化结构
MyStruct Obj = FillStruct(1, 2, 3, 4, 5);

但这不起作用。我收到了这个错误:

灵活数组成员的非静态初始化

我把Obj改成static初始化就可以编译代码了

static MyStruct Obj = FillStruct(1, 2, 3, 4, 5);

但是现在调试器给了我一些关于这个对象的奇怪信息。

那么我该如何解决这个问题呢?我正在寻找一种解决方案来在嵌入式设备(AVR MCU)上的编译期间初始化这个结构。在这种情况下,我不能使用带有malloc 等的解决方案。并且这个结构中的数据是恒定的并存储在程序内存中。所以应用程序只读取这些数据。

【问题讨论】:

  • 第二部分(static)似乎只是您的调试器的一个限制。在这种情况下,代码本身似乎很好。
  • 但是调试器给我0xC0AB作为长度,正确的长度必须是10。还是这个问题也来自限制?
  • 您是否考虑过使用 NARGS 宏 hack 在编译时使其成为固定大小而不是可变长度?
  • 当然,当我在我的系统上运行您的代码时,Obj.Length 设置为 20,正如我所期望的那样(sizeof(int) == 4 对我来说)。所以看起来这是你的调试器(或者你的编译器)行为不端。
  • @Kampi:我认为如果您提供解决方案作为正确答案会更好,然后您会接受它,我们可以投票。如果您没有“自学”徽章,您甚至会获得它。

标签: c struct


【解决方案1】:

我找到了一种解决方案。编译器抛出此错误,因为我声明并初始化了 main 内部的结构。将此段移出main 将解决此问题。

最终的解决方案是这样的:

#define VA_NARGS_IMPL(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, N, ...) 2 * N
#define VA_NARGS(...) VA_NARGS_IMPL(__VA_ARGS__, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1)

#define FillStruct(...)     { .Length = VA_NARGS(__VA_ARGS__), .Data = {__VA_ARGS__} }

const MyStruct Obj = FillStruct(1, 2, 3, 4, 5);

int main(void)
{
   int B = Obj.Data[2];
   // B = 3
}

所以现在一切都很好。 const 关键字似乎也出现了错误的调试器输出。但现在我可以删除 conststatic 以获得结构中的正确 Length(但不是 Data)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-07-17
    • 1970-01-01
    • 1970-01-01
    • 2020-10-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多