5

我有一个与 C 中的结构初始化有关的问题。我有一个结构:

struct TestStruct
{
u8 status;
u8 flag1;
u8 flag2;
};

我想要一个通用函数/宏来初始化这个结构并设置一个参数的值,例如状态=1,简单的方法是:

TestStruct t = {};
t.status = 1;

但是,通过这样做,我将 status 的值设置了两次,第一次在 init 函数中设置为 0,第二次将其设置为 1(优化没有帮助?)。
(请不要告诉我 t = {1,0,0} 我正在寻找一种通用方式)
我正在考虑 init 函数中的宏,例如:

#define INIT_TESTSTRUCT (param, value) \
{ .status=0, .flag1=0, .flag2=0, .param=value }
TestStruct t = INIT_TESTSTRUCT(status, 0);

但是,编译器给出错误“已覆盖初始化字段”,因为我已经设置了两次状态的值。

请帮助指出如何更改宏以实现我想要的,非常感谢。

4

3 回答 3

6
#define INIT_TESTSTRUCT(param, value) \
    { .param=(value) }
TestStruct t = INIT_TESTSTRUCT(status, 0);

应该这样做。然后将该变量添加到.data段中 - 因为它是一个初始化的变量 - 并且所有未明确提及的字段都由编译器(而不是链接器或加载器)设置为 0。

于 2013-11-08T21:52:21.963 回答
2

你在错误的地方有一个空间:

#define INIT_TESTSTRUCT(param, value) \
{ .status=0, .flag1=0, .flag2=0, .param=(value) }

应该这样做。

宏定义的(必须紧跟在宏名称之后。否则,解析器将其视为没有参数的宏并将其扩展为(param, value) ...etc...,在您的情况下,这显然是一个语法错误。

另请注意,在替换文本中放置参数通常是一个好主意(),以避免语法混乱。

于 2013-11-08T22:13:11.560 回答
1

嗯,首先

TestStruct t = {};

在 C 中是非法的。如果它在您的情况下编译,它必须是非标准编译器扩展。您可以通过以下方式达到相同的效果

TestStruct t = { 0 };

这在 C 中是合法的。它将整个结构中的所有字段设置为零。

其次,即使使用指定的初始化器,C 语言也遵循传统的“全有或全无”的初始化方法:如果您只初始化聚合的一个字段,则所有其他字段都被隐式初始化为零。

这意味着在您的情况下,您所要做的就是

TestStruct t = { .status = 1 };

初始化整个结构。status字段将设置为1,而所有其他字段将设置为零。

因此,您的宏可以实现为

#define INIT_TESTSTRUCT(param, value) { .param = value }
TestStruct t = INIT_TESTSTRUCT(status, 1);

无需将所有其他字段显式设置为零 - 它会自行发生。

于 2013-11-08T23:08:55.087 回答