Anonymous | Login | 2024-12-12 14:58 UTC |
Main | My View | View Issues | Change Log | Docs |
Viewing Issue Simple Details [ Jump to Notes ] | [ Issue History ] [ Print ] | ||||||
ID | Category | Severity | Type | Date Submitted | Last Update | ||
0000142 | [1003.1(2008)/Issue 7] System Interfaces | Objection | Error | 2009-09-03 18:45 | 2009-09-17 16:15 | ||
Reporter | cjwatson | View Status | public | ||||
Assigned To | ajosey | ||||||
Priority | normal | Resolution | Rejected | ||||
Status | Resolved | ||||||
Name | Colin Watson | ||||||
Organization | Canonical Ltd. | ||||||
User Reference | |||||||
Section | alphasort | ||||||
Page Number | ? | ||||||
Line Number | ? | ||||||
Interp Status | --- | ||||||
Final Accepted Text | |||||||
Summary | 0000142: alphasort prototype incompatible with qsort comparison function | ||||||
Description |
IEEE Std 1003.1-2008 declares alphasort as: int alphasort (const struct dirent **, const struct dirent **); Most pre-standard implementations of alphasort declared it as: int alphasort (const void *, const void *); This includes 4.3BSD, the BSDs in general, and GNU libc. (Linux libc 4 and 5 used const struct dirent **, according to the alphasort manual page on GNU/Linux, but the GNU C library 2.0 and later returned to the BSD prototype.) alphasort has often been used as a qsort comparison function, and its pre-standard type was amenable to this. Unfortunately, the type given in 1003.1-2008 is not. According to my best reading of C99, pointers to functions taking pointer arguments of different types are not of compatible type, and GCC issues a diagnostic. The effect of this is to require previously-correct (albeit non-standard) programs to either tolerate a diagnostic or use a wrapper function to mediate between qsort and alphasort. Neither seems very elegant. Note that the standard's page for qsort and alphasort refer to each other in their SEE ALSO sections, suggesting that they are intended to be used together. The qsort(3) manual page on at least my implementation (GNU/Linux) goes further and gives alphasort as an example of a function suitable for use as the comparison function. As such, it is likely that a reasonable body of code has been written with this assumption, and indeed the incompatible types were brought to my attention by a maintainer of a package including such code. As a test case, the following transcript shows a program (which omits error-checking for brevity) to write a sorted list of directory entries in the current directory to standard output. The transcript also includes the diagnostic produced using GCC 4.4.1 and glibc 2.10.1. <cjwatson@sarantium ~>$ cat sort.c #include <string.h> #include <stdlib.h> #include <stdio.h> #include <dirent.h> int main (int argc, char *argv[]) { DIR *dir; struct dirent *entry, **entries; int n_entries = 0, max_entries = 16, i; dir = opendir ("."); entries = malloc (max_entries * sizeof *entries); while ((entry = readdir (dir)) != NULL) { if (n_entries >= max_entries) { max_entries *= 2; entries = realloc (entries, max_entries * sizeof *entries); } entries[n_entries] = malloc (sizeof *entry); memcpy (entries[n_entries], entry, sizeof *entry); ++n_entries; } closedir (dir); qsort (entries, n_entries, sizeof *entries, alphasort); for (i = 0; i < n_entries; ++i) printf ("%s\n", entries[i]->d_name); return 0; } $ gcc -Wall -o sort sort.c sort.c: In function 'main': sort.c:26: warning: passing argument 4 of 'qsort' from incompatible pointer type /usr/include/stdlib.h:710: note: expected '__compar_fn_t' but argument is of type 'int (*)(const struct dirent **, const struct dirent **)' |
||||||
Desired Action |
Ideally, POSIX should return to the BSD prototype so that alphasort and qsort are compatible again. This would also involve a change to scandir to avoid the same problem in reverse. Implementations might need to use feature test macros to use different declarations depending on the version of POSIX requested. Less ideally, a standard typedef for qsort's comparison function would help, to make it easier to use casts. However, casts are of course a good way to bypass type-safety and so this would not be a particularly good solution in itself. |
||||||
Tags | No tags attached. | ||||||
Attached Files | |||||||
|
Mantis 1.1.6[^] Copyright © 2000 - 2008 Mantis Group |