Posted on Sat Feb 18, 2017
In my CCEvents project (still in early development) I
started using “small” data structures as values. I’m talking about structures that
are 2, 3 or 4 words in size, like posix’s struct timeval
and these ones:
struct ccevents_timeval_t { struct timeval; }; struct ccevents_timeout_t { long int seconds; long int milliseconds; long int microseconds; };
So I write code like this:
#include <ccevents.h> cce_location_t L[1]; if (cce_location(L)) { cce_run_error_handlers(L); cce_condition_free(cce_condition(L)); } else { ccevents_timeout_t to = ccevents_timeout_init(L, 1, 2, 3); ccevents_timeval_t tv = ccevents_timeout_start(L, to); if (ccevents_timeval_is_expired_timeout(tv)) { /* do something */ } cce_run_cleanup_handlers(L); }
and just accept the performance penalty of copying data structures on the stack both as parameters and return values.
I find the code significantly clearer to write without pointers; there are no
NULL
pointers problems; memory allocation management is simpler; there is less
sharing of contexts; and I can also specify significant gcc attributes for
functions that I could not add when using pointers (some functions become
‘leaf’, ‘const’ or ‘pure’; see gcc’s documentation for details).