从变量初始化结构中的字段

Initializing fields in structs from variables

我正在尝试从通过变量传递的常量值初始化结构中的字段。

typedef struct _A{
    uint a;
}A;
const A a = {9} ; const A b = { .a = 10 }; const A c = {0};

typedef struct _Z{
    A a;
    A b;
    A c;
}Z;
Z z = { a,b,c };

但这会产生编译器错误:initializer element is not constant 什么不是那么明显,因为 a、b 和 c 被声明为常量,在运行时不应修改。

我想在记忆中得到的是这样的:

0x00 9
0x04 10
0x08 0

因为结构只是一个整数数组。

现在的问题是我如何告诉编译器(使用 arm-none-eabi-gcc)变量 abc 是像 defines 和 can/should 一样被它们的内容替换,因为对 z 的唯一引用将出现在 运行 程序中?
也许是一些 pragma 甚至预处理器指令?

我在初始化 a 的同一个宏中构造 A。看起来像这样,但有点复杂。

#define bar(name, ...)\
typedef struct __bar_##name{\
    List(applydef, __VA_ARGS__)\
}bar_##name;\
const bar_##name name ={List(applyset, __VA_ARGS__)};
bar(foobar, a,b)

以上代码由于过多使用定义而自行扩展。 我在这里接受的另一种解决方案是不生成新的结构,而是生成一个新的定义,我可以像这样将其放入宏中。

不幸的是,初始化程序 {a,b,c} 不是常量,但您对 z 的声明要求它是常量。

[C99: 6.6/7]: More latitude is permitted for constant expressions in initializers. Such a constant expression shall be, or evaluate to, one of the following:

  • an arithmetic constant expression,
  • a null pointer constant,
  • an address constant, or
  • an address constant for an object type plus or minus an integer constant expression.

[C99: 6.7.8/4]: All the expressions in an initializer for an object that has static storage duration shall be constant expressions or string literals.

z 具有静态存储持续时间,因为您在全局范围内声明了它。如果您将其声明移动到函数中,则此规则将不适用。

名称 abc 中的

None 符合常量表达式的条件,尽管您使用 const:

[C99: 6.6/8]: An arithmetic constant expression shall have arithmetic type and shall only have operands that are integer constants, floating constants, enumeration constants, character constants, and sizeof expressions. Cast operators in an arithmetic constant expression shall only convert arithmetic types to arithmetic types, except as part of an operand to a sizeof operator whose result is an integer constant.

尽管 struct _S 只是包裹了一个 uint,但这并不意味着它 一个 uint。事实上,关于 struct _Z,你断言 “结构只是一个整数数组” 是错误的:你没有考虑类型。

C++在这方面比C宽松很多,尤其是在constexpr.

时代