How to remove this (not portable) nested function?

I have a function that sorts a list of pointers to structures (implementation omitted):

void sort_by(struct thing **start, int size,
    int (*cmp_by)(struct thing *, struct thing *));

This feature allows me to pass a comparison function cmp_bythat takes two structures and returns 1, 0, -1if necessary. Then there is such a function (GCC-only!):

void reverse_by(struct thing **start, int size,
        int (*cmp_by)(struct thing *, struct thing *)) {

    int cmp_reverse(struct thing *a, struct thing *b) {
        return -cmp_by(a, b);
    }

    sort_by(start, size, cmp_reverse);
}

This function takes the same arguments as sort_by, but cancels the sort order by reversing the sign of the comparison result. GCC has this extension to allow nested functions. How reverse_bycan I write portable? Even my attempts to get this to work don't come close to compiling:

int (*reverse(int (*fn)(struct thing *, struct thing *)))(struct thing *, struct thing *) {
    return -fn;  /* OBVIOUSLY AND CONCEPTUALLY WRONG */
}
int (*reverse(int (*fn)(struct thing *a, struct thing *b)))(struct thing *x, struct thing *y) {
    return -fn(a, b);  /* WRONG RETURN TYPE WRONG WRONG */
}
int (*reverse(int (*fn)(struct thing *a, struct thing *b)))(struct thing *x, struct thing *y) {
    return -fn(x, y);  /* YOU HAVE NO IDEA WHAT YOU'RE DOING STOP GUESSING */
}

, reverse_by ( sort_by), , ? / , .

+4
1

, :

typedef int (*cmp_func)(struct thing *, struct thing *);

static cmp_func reverse_cmp_by_impl;

static int cmp_reverse(struct thing *a, struct thing *b) {
    int ret;
    cmp_func impl = reverse_cmp_by_impl;
    ret = -impl(a, b);
    reverse_cmp_by_impl = impl; // For re-entrancy
    return ret;
}

void reverse_by(struct thing **start, int size, cmp_func cmp_by) {
    reverse_cmp_by_impl = cmp_by;
    sort_by(start, size, cmp_reverse);
}

, sort_by. , reverse_by , .

+1

Source: https://habr.com/ru/post/1538617/


All Articles