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 :)