From: Michael Vogt Date: Sun, 29 Mar 2026 10:46:28 +0000 (+0200) Subject: many: use POINTER_MAY_BE_NULL in inner sort _cmp funcs X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=bb94af45c1e8fd87127ac875a09a8efa80df4fb6;p=thirdparty%2Fsystemd.git many: use POINTER_MAY_BE_NULL in inner sort _cmp funcs Some functions are in the hot path of a sort. While it is more correct to also use assert() here for the passed pointers it is also a runtime cost that should never be needed when e.g. qsort() is used as it will always pass non-NULL pointers. So for these critical functions use POINTER_MAY_BE_NULL() which is compiled out and add a comment to them. Not all _compare() functions are changed, it was a bit of a judgement call because some (like ether_addr_compare) are not called with that much data. But happy to get advise here and tweak accordingly. --- diff --git a/src/basic/sort-util.c b/src/basic/sort-util.c index 2859f14376e..a76a6c85a82 100644 --- a/src/basic/sort-util.c +++ b/src/basic/sort-util.c @@ -65,15 +65,19 @@ void qsort_r_safe(void *base, size_t nmemb, size_t size, comparison_userdata_fn_ } int cmp_int(const int *a, const int *b) { - assert(a); - assert(b); + /* This is called from qsort()s inner loops. Correctly implemented qsort will never pass NULL so we + just suppress the check via POINTER_MAY_BE_NULL instead of assert() to avoid the runtime cost. */ + POINTER_MAY_BE_NULL(a); + POINTER_MAY_BE_NULL(b); return CMP(*a, *b); } int cmp_uint16(const uint16_t *a, const uint16_t *b) { - assert(a); - assert(b); + /* This is called from qsort()s inner loops. Correctly implemented qsort will never pass NULL so we + just suppress the check via POINTER_MAY_BE_NULL instead of assert() to avoid the runtime cost. */ + POINTER_MAY_BE_NULL(a); + POINTER_MAY_BE_NULL(b); return CMP(*a, *b); } diff --git a/src/basic/strv.c b/src/basic/strv.c index 5e4d46bde4d..4044a129c60 100644 --- a/src/basic/strv.c +++ b/src/basic/strv.c @@ -844,8 +844,10 @@ bool strv_overlap(char * const *a, char * const *b) { } static int str_compare(char * const *a, char * const *b) { - assert(a); - assert(b); + /* This is called from qsort()s inner loops. Correctly implemented qsort will never pass NULL so we + just suppress the check via POINTER_MAY_BE_NULL instead of assert() to avoid the runtime cost. */ + POINTER_MAY_BE_NULL(a); + POINTER_MAY_BE_NULL(b); return strcmp(*a, *b); } diff --git a/src/core/job.c b/src/core/job.c index 638e6e759e5..7dd8a4617db 100644 --- a/src/core/job.c +++ b/src/core/job.c @@ -1525,10 +1525,10 @@ void job_add_to_gc_queue(Job *j) { } static int job_compare_id(Job * const *a, Job * const *b) { - assert(a); - assert(b); - assert(*a); - assert(*b); + /* This is called from qsort()s inner loops. Correctly implemented qsort will never pass NULL so we + just suppress the check via POINTER_MAY_BE_NULL instead of assert() to avoid the runtime cost. */ + POINTER_MAY_BE_NULL(a); + POINTER_MAY_BE_NULL(b); return CMP((*a)->id, (*b)->id); } diff --git a/src/shared/format-table.c b/src/shared/format-table.c index eb1866e8d4a..55e19ebd70f 100644 --- a/src/shared/format-table.c +++ b/src/shared/format-table.c @@ -1543,8 +1543,10 @@ static int cell_data_compare(TableData *a, size_t index_a, TableData *b, size_t static int table_data_compare(const size_t *a, const size_t *b, Table *t) { int r; - assert(a); - assert(b); + /* This is called from qsort()s inner loops. Correctly implemented qsort will never pass NULL so we + just suppress the check via POINTER_MAY_BE_NULL instead of assert() to avoid the runtime cost. */ + POINTER_MAY_BE_NULL(a); + POINTER_MAY_BE_NULL(b); assert(t); assert(t->sort_map);