Default values in a C Struct

I have a data structure like this:

struct foo {
    int id;
    int route;
    int backup_route;
    int current_route;
}

and a function called update() that is used to request changes in it.

update(42, dont_care, dont_care, new_route);

this is really long and if I add something to the structure I have to add a 'dont_care' to EVERY call to update( ... ).

I am thinking about passing it a struct instead but filling in the struct with 'dont_care' beforehand is even more tedious than just spelling it out in the function call. Can I create the struct somewhere with default values of dont care and just set the fields I care about after I declare it as a local variable?

struct foo bar = { .id = 42, .current_route = new_route };
update(&bar);

What is the most elegant way to pass just the information I wish to express to the update function?

and I want everything else to default to -1 (the secret code for 'dont care')


While macros and/or functions (as already suggested) will work (and might have other positive effects (i.e. debug hooks)), they are more complex than needed. The simplest and possibly most elegant solution is to just define a constant that you use for variable initialisation:

const struct foo FOO_DONT_CARE = { // or maybe FOO_DEFAULT or something
    dont_care, dont_care, dont_care, dont_care
};
...
struct foo bar = FOO_DONT_CARE;
bar.id = 42;
bar.current_route = new_route;
update(&bar);

This code has virtually no mental overhead of understanding the indirection, and it is very clear which fields in bar you set explicitly while (safely) ignoring those you do not set.


You can change your secret special value to 0, and exploit C's default structure-member semantics

struct foo bar = { .id = 42, .current_route = new_route };
update(&bar);

will then pass 0 as members of bar unspecified in the initializer.

Or you can create a macro that will do the default initialization for you:

#define FOO_INIT(...) { .id = -1, .current_route = -1, .quux = -1, ## __VA_ARGS__ }

struct foo bar = FOO_INIT( .id = 42, .current_route = new_route );
update(&bar);