Search code examples
cgccqsortfunction-prototypes

Calling the qsort() function


I'm writing this program which needs to do a qsort() on a table. I've done extensive research on the internet, but I'm still missing something. Below is selected portions of the source code.

#define NOSLACK __attribute__((packed))

#define TABWIDTH 100                                 /* width of big table */

#define TABSIZE 100                      /* number of entries in big table */

struct ELEMEN 
   {char flags;                           /* flags pertaining to this task */
    short int tasknum;  /* number of THIS task (excluding any step number) */
    short int numpre;                   /* number of prereqs this task has */
    short int numpost;                 /* number of postreqs this task has */
    short int prereqs[0];      /* table of prereqs (omitted if numpre = 0) */
    short int postreqs[0];   /* table of postreqs (omitted if numpost = 0) */
    char fragment[TABWIDTH                    /* fragment of the descrip-  */
     - sizeof(char)                           /* tion; as much as will fit */
     - sizeof(short int) * 3];} NOSLACK;

           /* the lengths of all the above fields should total to TABWIDTH */

    struct ELEMEN bigtable[TABSIZE];

short int e35(const void*, const void*);

short int main(int argc, char* argv[])

    qsort(g.bigtable, numelem, TABWIDTH,         /* sort table using e35() */
     e35);                                         // <--- PROBLEM HERE

short int e35(const void* elem1, const void* elem2)         /* sort tasks  */
   {return(memcmp(                                          /* into se-    */
     (short int*)&((struct ELEMEN*)elem1)-> tasknum,        /* quence by   */
     (short int*)&((struct ELEMEN*)elem2)-> tasknum,        /* task number */
     sizeof(short)
     ));

The problem is in the call to qsort(). If the last parameter is just e35, I get the warning message: warning: passing argument 4 of ‘qsort’ from incompatible pointer type [-Wincompatible-pointer-types]

If I change e35 to (e35)(const void*)(const void*)), I get: error: expected expression before ‘const’ and error: too few arguments to function ‘e35’

If I change it to error: e35(asterisk)(const void*)(const void*)) I get: error: expected expression before ‘)’ token error: too few arguments to function ‘e35’ and error: expected expression before ‘const’

What am I missing? I believe gcc doesn't know that e35 is a function, rather than a variable or an array.

I've used qsort() before, but this is the first time under gcc. Previously, I've used it under TurboC, where all I need is the name of the function, e35.

I'm compiling using gcc under Debian Linux. The purpose of the qsort() is that I repeatedly search the table later, and want to be able to do that quicker.

(Side question, just for fun: why have I called the comparing routine e35? Where is that from and what's the significance? Perhaps I should have put this side question on either puzzing or retrocomputing instead.)


Solution

  • Use an int return. Drop unnecessary casts. Compare as short. Avoid subtraction overflow.

    int e35(const void* elem1, const void* elem2) {
      const struct ELEMEN* t1 = elem1;
      const struct ELEMEN* t2 = elem2;
      return (t1->tasknum > t2->tasknum) - (t1->tasknum < t2->tasknum);
    }