In our code we have a big struct of mixed types, and want to store a duplicate (const) struct of default values for these.
When the user want to default a setting, it would be nice to be able to do this by just taking the address offset of the item within the struct, and then assign the value with the same offset in the “defaults” struct, a bit like this:
void *setting = &settings->thing; // Points to a setting
int offset = setting - &settings;
void *default = &defaults_struct + offset; // Points to the default value
*setting = *default; // Set setting to default value
The idea being that if settings->thing points to an int8, the int8 value is copied from defaults, but if settings->other_thing is an int32, the full 32-bits are copied over.
The question is, does this work with void pointers as I’ve described above? If not, is there a way of doing this? Am I missing a better way of achieving this?
Edit to clarify: We want to set a single value within the struct to the corresponding value within the “defaults” struct.
No, this doesn’t work. Pointers of type
void *don’t have a size associated with them, i.e. it’s unknown what data type they point at. It follows that you can’t do the assignment like that, either.You should probably just copy from the defaults directly, as suggested in a comment.
Also note that
defaultis a reserved word in C, so you shouldn’t use it for a variable.If the defaults are globally visible, you might define a macro to hide this:
The user (which I assume is a developer) can now do:
That said, I would (as a developer) prefer something like:
This is more clear, and less magic. Sure, it probably takes more time to copy all the fields, but settings are generally not performance-critical.
Note that the above function might just be:
Which neatly encapsulates the default values, and removes the global.