When designing a C API for configuring a library/utility, I have a co-worker who prefers to lump all configuration parameters into 1 function call. For example:
int set_diagnostic_email_config( char *to_address,
bool include_timestamp,
bool send_for_crashes,
bool send_daily_status,
bool send_on_event1,
bool send_on_event2 )
A similar “get” function exists with many parameters.. The main advantage of this method is that if someone adds a new option, e.g., “bool send_on_event3”, then because the prototype changed you are forced to update every place this function call is used (assuming there are multiple places where people call this).
I prefer something along the lines of:
int get_diagnostic_email_config( struct email_config *p_config );
int set_diagnostic_email_config( struct email_config *p_config );
where you just change the structure elements as needed. But… if someone updates the email_config” structure it doesn’t force people to update all the places where it is used (even though we often want to..). Plus my co-worker complains that if someone just tries to initialize “email_config” by hand, then if things get added later then those new fields will be uninitialized with no warnings.
Is there any strong consensus on which method is preferred? or perhaps there is another alternative I’m missing?
A struct is better than a long list. Long list is hard to maintain, as nobody remembers the exact order.
You can create a constructor that fills this struct with safe (default and/or invalid) entries. Always (probably in the accessor function) checking for invalid values will make it easy to spot errors in initialization.
You can hide a magic number in this struct. The first field is CONFIG_MAGIC that needs to be equal to a constant that you defined. You set this field in the constructor and expect to be set at all times. This you avoid somebody just malloc()ing the struct and initalizing it by hand. Such programmer would need to learn about this CONFIG_MAGIC constant and is more than likely to find and use the proper constructor.