This is the mail archive of the
mailing list for the GCC project.
Re: [PATCH] Remove a pointless global var
- From: Alexander Monakov <amonakov at ispras dot ru>
- To: Richard Biener <rguenther at suse dot de>
- Cc: gcc-patches at gcc dot gnu dot org, giuliano dot belinassi at usp dot br
- Date: Mon, 22 Jul 2019 16:27:31 +0300 (MSK)
- Subject: Re: [PATCH] Remove a pointless global var
- References: <alpine.LSU.firstname.lastname@example.org>
On Mon, 22 Jul 2019, Richard Biener wrote:
> I've noticed that we have quite some instances using qsort
> and passing down state to the comparator via a global var.
> Now that we have our own qsort implementation I wonder what
> the best course of action is to add a variant passing down
> such state to the comparator? Copying nearly the whole
> implementation would be possible but also some marshalling
> of three-argument comparator calls to two-argument functions
> (and some ABIs can do without actual marshalling). The
> other option is templating everything (ugh).
I think there are three choices.
1. Have gcc/sort.cc implement only qsort_r, use a "universal comparator
int cmp2to3(void *a, void *b, void *ctx)
return (int (*)(void *, void *))ctx(a, b);
to adapt existing qsort uses.
2. Have gcc/sort.cc implement both qsort and qsort_r by duplicating code,
either copying manually (ugh) or by turning netsort, mergesort, qsort_chk
3. Have gcc/sort.cc implement only qsort_r, but have existing qsort callers
pass their comparators to a fancy C++ "universal comparator adapter" so
they can be inlined into the three-argument wrapper and thus
speed/size penalties are tiny (only from always loading the context pointer
that is ignored by legacy two-argument comparators):
void qsort_r(void *, size_t, size_t, int cmp(void *, void *, void *));
template<int cmp(void *, void *)>
int cmp2to3(void *a, void *b, void *c)
return cmp(a, b);
#define qsort(base, sz, n, cmp) \
qsort_r(base, sz, n, cmp2to3<cmp>)
static int my_cmp(void *a, void *b)
void test(void *base, size_t sz, size_t n)
qsort(base, sz, n, my_cmp);