qsort(3)

๐Ÿ’– qsort(3) โ€” Library Functions Manual ๐Ÿ’–

okay bestie, gather round, because today we're talking about qsort and qsort_r โ€” the literal sort an array girlies of the C standard library. no cap, this one's a classic. โœจ


๐ŸŒธ NAME ๐ŸŒธ

qsort, qsort_r โ€” sort an array ๐Ÿซถ

๐Ÿ“š LIBRARY ๐Ÿ“š

Standard C library (libc, -lc) โ€” yeah she lives in libc, she's been there forever, iconic behavior.

โœจ SYNOPSIS โœจ

#include <stdlib.h>

void qsort(size_t n, size_t size;
           void base[n * size], size_t n, size_t size,
           typeof(int (const void [size], const void [size]))
               *compar);
void qsort_r(size_t n, size_t size;
           void base[n * size], size_t n, size_t size,
           typeof(int (const void [size], const void [size], void *))
               *compar,
           void *arg);

๐ŸŽ€ Feature Test Macro Requirements for glibc (see feature_test_macros(7)) ๐ŸŽ€

  • qsort_r():
    • _GNU_SOURCE

like, that's the whole vibe check. if you want qsort_r you need _GNU_SOURCE. periodt. ๐Ÿ’…


๐Ÿ’… DESCRIPTION ๐Ÿ’…

so the tea is: qsort() sorts an array with n elements, each of them size bytes big. the base argument points to the very start of that array. she's your girl. ๐ŸŒธ

and here's how she decides the order: the contents of the array get sorted into ascending order according to a comparison function that compar points to. that function gets called with two arguments, and those two arguments point to the objects being compared. so like, she's handing your callback two pointers and being like "okay you decide, i trust you". ๐Ÿ˜Œ

now the comparison function itself has RULES, bestie, and you cannot skip them:

the comparison function must return an integer that is less than, equal to, or greater than zero, depending on whether the first argument is considered respectively less than, equal to, or greater than the second one.

and the part you need to clock: if two members compare as equal, their order in the sorted array is undefined. so no, she's not stable, don't come for her about it, it's literally in the docs. ๐Ÿ™ˆ

then we have qsort_r() โ€” she is identical to qsort() except that her comparison function compar takes a third argument. a pointer gets passed to the comparison function through arg. and the reason this is lowkey genius is: that way your comparison function doesn't have to reach for global variables to smuggle in arbitrary arguments, which makes her reentrant and safe to use in threads. main character energy fr fr. ๐Ÿ‘‘


โญ RETURN VALUE โญ

qsort() and qsort_r() return no value. nothing. nada. she does the work and she does not report back, she's mysterious like that. ๐Ÿฆ‹


๐ŸŒˆ ATTRIBUTES ๐ŸŒˆ

for an explanation of the terms used in this section, see attributes(7).

  • Interface: qsort(), qsort_r()
  • Attribute: Thread safety
  • Value: MT-Safe

so basically: MT-Safe, meaning she's not gonna fight with your other threads. slay. ๐Ÿ’–


๐Ÿ‘‘ STANDARDS ๐Ÿ‘‘

  • qsort()
    • C11, POSIX.1-2008.

๐Ÿ•ฐ๏ธ HISTORY ๐Ÿ•ฐ๏ธ

  • qsort()
    • POSIX.1-2001, C89, SVr4, 4.3BSD.
  • qsort_r()
    • glibc 2.8.

an elder. a legend. a pioneer in her field. ๐Ÿ’œ


๐Ÿ“ NOTES ๐Ÿ“

if you wanna compare C strings, your comparison function can just call strcmp(3) โ€” the example down below shows exactly how. iykyk. โœจ


๐Ÿงš EXAMPLES ๐Ÿงš

for one example of use, go peek at the example under bsearch(3). ๐Ÿซถ

another example is the following program, which sorts the strings given in its command-line arguments:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

static int
cmpstringp(const void *p1, const void *p2)
{
    /* The actual arguments to this function are "pointers to
       pointers to char", but strcmp(3) arguments are "pointers
       to char", hence the following cast plus dereference.  */

    return strcmp(*(const char **) p1, *(const char **) p2);
}

int
main(int argc, char *argv[])
{
    if (argc < 2) {
        fprintf(stderr, "Usage: %s <string>...\n", argv[0]);
        exit(EXIT_FAILURE);
    }

    qsort(&argv[1], argc - 1, sizeof(char *), cmpstringp);

    for (size_t j = 1; j < argc; j++)
        puts(argv[j]);
    exit(EXIT_SUCCESS);
}

okay so look at that comment in cmpstringp โ€” that's the whole trick: the actual arguments are "pointers to pointers to char", but strcmp(3) wants "pointers to char", hence the cast plus dereference. write that down bestie, that's the part everyone gets wrong on the first try. ๐Ÿ˜ญ๐Ÿ”ฅ


๐Ÿ”ฅ SEE ALSO ๐Ÿ”ฅ

sort(1), alphasort(3), strcmp(3), versionsort(3)


and that's the whole page, babe! this gorgeous little number came to you from Linux man-pages 6.20, dated 2026-02-08 โ€” go forth and sort responsibly ๐ŸŽ€โœจ๐Ÿ’–

๐Ÿ“ฆ where this page comes from
  • arch rolling: man-pages 6.20-1 ยท BSD-2-Clause AND BSD-3-Clause AND BSD-4.3TAHOE AND BSD-4-Clause-UC AND GPL-1.0-or-later AND GPL-2.0-only AND GPL-2.0-or-later AND GPL-3.0-or-later AND LGPL-3.0-linking-exception AND LGPL-3.0-or-later AND LicenseRef-Public-Domain AND LicenseRef-UltraPermissive AND Linux-man-pages-1-para AND Linux-man-pages-copyleft AND Linux-man-pages-copyleft-2-para AND Linux-man-pages-copyleft-var AND MIT AND Spencer-94
  • nixpkgs unstable: man-pages 6.20
  • ๐Ÿ“œ the page's license: Linux-man-pages-copyleft
  • ๐Ÿ’– girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms