On Fri, Oct 05 2018, Jeff King wrote: > On Fri, Oct 05, 2018 at 12:59:02AM +0200, René Scharfe wrote: > >> We could also do something like this to reduce the amount of manual >> casting, but do we want to? (Macro at the bottom, three semi-random >> examples at the top.) >> [...] >> diff --git a/git-compat-util.h b/git-compat-util.h >> index 5f2e90932f..f9e78d69a2 100644 >> --- a/git-compat-util.h >> +++ b/git-compat-util.h >> @@ -1066,6 +1066,18 @@ static inline void sane_qsort(void *base, size_t nmemb, size_t size, >> qsort(base, nmemb, size, compar); >> } >> >> +#define DEFINE_SORT(name, elemtype, one, two, code) \ >> +static int name##_compare(const void *one##_v_, const void *two##_v_) \ >> +{ \ >> + elemtype const *one = one##_v_; \ >> + elemtype const *two = two##_v_; \ >> + code; \ >> +} \ >> +static void name(elemtype *array, size_t n) \ >> +{ \ >> + QSORT(array, n, name##_compare); \ >> +} > > Interesting. When I saw the callers of this macro, I first thought you > were just removing the casts from the comparison function, but the real > value here is the matching QSORT() wrapper which provides the type > safety. > > I'm not wild about declaring functions inside macros, just because it > makes tools like ctags like useful (but I have certainly been guilty of > it myself). I'd also worry that taking "code" as a macro parameter might > not scale (what happens if the code has a comma in it?) There's always the option of generating the C code as part of some build step and carrying around a big C file with various type-safe functions that only differ in the types they operate on. It can even be committed to source control. That sucks in some ways for sure, but is a lot friendlier for grepping, ctags etc. I've just barely resisted the urge to include that thread where we were discussing making the code C++-compiler compatible in the References header :)