Reputation: 455
I have a question related to struct initialization in C. I have a struct:
struct TestStruct
{
u8 status;
u8 flag1;
u8 flag2;
};
I want a generic function/macro to initialize this struct and set the value of one parameter, eg status =1, easy way is:
TestStruct t = {};
t.status = 1;
However, by doing this I have set the value of status twice, first to 0 in init function and second set it to 1 (optimization does not help?).
(Please dont tell me t = {1,0,0} Im looking for a generic way)
I am thinking about a macro in init function, something like:
#define INIT_TESTSTRUCT (param, value) \
{ .status=0, .flag1=0, .flag2=0, .param=value }
TestStruct t = INIT_TESTSTRUCT(status, 0);
However, the compiler gives error "initialized field overwritten", because I have set the value of status twice.
Please help to point out how to alter the macro to achieve what I want, many thanks.
Upvotes: 5
Views: 8320
Reputation: 91059
#define INIT_TESTSTRUCT(param, value) \
{ .param=(value) }
TestStruct t = INIT_TESTSTRUCT(status, 0);
should do it. The variable is then added in .data
segment - as it is an initialized one - and all fields which are not mentionned explicitly are set to 0 by the compiler (instead of the linker or the loader).
Upvotes: 6
Reputation: 320551
Well, firstly
TestStruct t = {};
is illegal in C. If it compiled in your case, it must be a non-standard compiler extension. You can achieve the same effect by
TestStruct t = { 0 };
which is legal in C. It sets all fields in the entire struct to zeros.
Secondly, even with designated initializers C language follows the traditional "all-or-nothing" approach to initialization: if you initialize just one field of the aggregate, all other fields are implicitly initialized to zero.
Which means that in your case all you have to do is
TestStruct t = { .status = 1 };
to initialize the entire struct. status
field will be set to 1
, while all other fields will be set to zero.
So, your macro can be implemented as
#define INIT_TESTSTRUCT(param, value) { .param = value }
TestStruct t = INIT_TESTSTRUCT(status, 1);
There's no need to explicitly set all other fields to zero - it will happen by itself.
Upvotes: 1
Reputation: 78923
You have a space in the wrong place:
#define INIT_TESTSTRUCT(param, value) \
{ .status=0, .flag1=0, .flag2=0, .param=(value) }
should do it.
The (
of the macro definition must come immediately after the macro name. Otherwise the parser takes this as a macro with no arguments and expands it to (param, value) ...etc...
and in your case this then obviously is a syntax error.
Also note that it is usually a good idea to put ()
around parameters in the replacment text, to avoid syntax confusion.
Upvotes: 2