On Sat, Apr 28, 2018 at 5:59 AM, Branko Čibej <br...@apache.org> wrote:

> On 27.04.2018 21:23, Greg Stein wrote:
> > At one point, we used to use an svn_array_find() or some such. We
> > deprecated it. Creating a function to do comparisons, then set up a
> > function call... It was just annoying. Iteration over an APR array is
> > easy, and very clear. There is basically no code or mental overload.
> > Using a comparator function, there is.
>
>     static int compare(const void* x, const void* y) {
>        return strcmp(*(const char**) x, (const char*) y));
>        // Oops ... is the first argument the pointer to the
>        // array element and the second the search key, or is
>        // it the other way around? Or do we have to dereference
>        // the search key in order to make these arguments
>        // symmetric?
>     }
>
>     // ... lots of code in between
>
>     int i = apr_array_find(array, compare, "key");
>
> The first form is definitely easier to understand and nicely localized.
> "Explicit is better than implicit" and all that.
>

If you wanted to pursue this, I'd definitely apr_{type}_compare_set()
the comparator callback at array creation. Saves stack prep on lots
of calls, and avoids individual errors passing a comparator off in
some infrequently used code path. Use apr_uintptr_t if you want to
portably pass an int-or-ptr portably as the lhs/rhs argument. But
Greg makes a good case for comparing structs passed on the stack
(svn_errno is such a struct), and this requires the _compare_set()
to accept an incomplete type. This likely can't be done in 1.x (and
would be problematic when porting certain code to 2.x) because
apr_array_t was a very transparent type (where to hide the pointer
to comparator fn?)

Reply via email to