Paul Eggert wrote:
It's not just an academic point. Without the patch, 'zic /dev/null' dumps core on Fedora 36 x86-64... The core dump occurred because GCC translates this: qsort(links, nlinks, sizeof *links, qsort_linkcmp); as if it were this:
if (nlinks == 0) __builtin_trap(); qsort(links, nlinks, sizeof *links, qsort_linkcmp);
This is an astonishing result. It's hard to imagine it's worthwhile for gcc to perform this "optimization". There are some decent resident language lawyers over on Stack Overflow these days. I asked this question there, and several posters have cited language from C17 which seems (like the Posix language others have mentioned here) to directly contraindicate gcc's behavior: These utilities [qsort, bsearch] make use of a comparison function to search or sort arrays of unspecified type. Where an argument declared as size_t nmemb specifies the length of the array for a function, nmemb can have the value zero on a call to that function; the comparison function is not called, a search finds no matching element, and sorting performs no rearrangement. Pointer arguments on such a call shall still have valid values, as described in 7.1.4. [C17 Sec. 7.22.5] https://stackoverflow.com/questions/74207802/qsort-with-size-0 THe only explanation I can think of is that gcc somehow knows that it is calling a recursive `qsort` implementation where the caller is responsible for terminating the recursion -- but even then, surely the behavior on n == 0 should be to do nothing (that is, as if void qsort() had returned immediately) rathern than to gratuitiously abort! Paul, which version of gcc is this, and what is $(GCC_DEBUG_FLAGS) expanding to?