qsort warning

M

monkeys paw

Compiling the following code gives me this warning:

headsort.c: In function `main':
headsort.c:22: warning: passing arg 4 of `qsort' from incompatible
pointer type

Anyone know why??


Code:
int strcompare(void *p1, void *p2) {
return strcmp((char *)p1, (char *)p2);
}

int main()
{
char *ary[] = { "abc", "zyx", "qrt", "123", "cba", "mud"};
size_t nelems, i;

nelems = sizeof(ary) / sizeof(char *);

printf("%d\n", nelems);

qsort((void *)ary, (size_t)nelems, sizeof(ary[0]), strcompare);

printf("\nSorted list:");
for (i=0; i<nelems; i++) {
printf(" %s ", ary);
}
 
R

Russell Hanneken

monkeys paw said:
Compiling the following code gives me this warning:

headsort.c: In function `main':
headsort.c:22: warning: passing arg 4 of `qsort' from incompatible
pointer type

Anyone know why??

Code:
int strcompare(void *p1, void *p2) {
return strcmp((char *)p1, (char *)p2);
}
[. . .]

qsort((void *)ary, (size_t)nelems, sizeof(ary[0]), strcompare);

Your compiler is complaining because strcompare is supposed to take
parameters of type const void *, not void * (note the const).

Also, be aware that your strcompare function will receive pointers to
elements of your array, and in this case each element is a char *. So you
need to cast p1 and p2 to const char **, not char *.

In short, strcompare should be something like this:

int strcompare(const void *p1, const void *p2) {
return strcmp(*((const char **)p1), *((const char **)p2));
}
 
D

Darrell Grainger

Compiling the following code gives me this warning:

headsort.c: In function `main':
headsort.c:22: warning: passing arg 4 of `qsort' from incompatible
pointer type

Anyone know why??

Code:
int strcompare(void *p1, void *p2) {
return strcmp((char *)p1, (char *)p2);
}

The qsort function is expecting (int (*)(const void *, const void *)) but
you are giving it (int (*)(void *, void *)).

Just curious, why the wrapper? Couldn't you just use:

qsort((void *)ary, (size_t)nelems, sizeof(ary[0]), strcmp);
int main()
{
char *ary[] = { "abc", "zyx", "qrt", "123", "cba", "mud"};
size_t nelems, i;

nelems = sizeof(ary) / sizeof(char *);

printf("%d\n", nelems);

qsort((void *)ary, (size_t)nelems, sizeof(ary[0]), strcompare);

printf("\nSorted list:");
for (i=0; i<nelems; i++) {
printf(" %s ", ary);
}
 
M

monkeys paw

qsort((void *)ary, (size_t)nelems, sizeof(ary[0]), strcompare);
Your compiler is complaining because strcompare is supposed to take
parameters of type const void *, not void * (note the const).

Also, be aware that your strcompare function will receive pointers to
elements of your array, and in this case each element is a char *. So you
need to cast p1 and p2 to const char **, not char *.

In short, strcompare should be something like this:

int strcompare(const void *p1, const void *p2) {
return strcmp(*((const char **)p1), *((const char **)p2));
}

Thanks for the info. Is there any difference between:
return strcmp(*((const char **)p1), *((const char **)p2));

-OR-

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

monkeys paw

Darrell said:
The qsort function is expecting (int (*)(const void *, const void *)) but
you are giving it (int (*)(void *, void *)).

Just curious, why the wrapper? Couldn't you just use:

qsort((void *)ary, (size_t)nelems, sizeof(ary[0]), strcmp);

It works, but results in the original warning message.
headsort.c:22: warning: passing arg 4 of `qsort' from incompatible
int main()
{
char *ary[] = { "abc", "zyx", "qrt", "123", "cba", "mud"};
size_t nelems, i;

nelems = sizeof(ary) / sizeof(char *);

printf("%d\n", nelems);

qsort((void *)ary, (size_t)nelems, sizeof(ary[0]), strcompare);

printf("\nSorted list:");
for (i=0; i<nelems; i++) {
printf(" %s ", ary);
}

 
E

Eric Sosman

Darrell said:
Compiling the following code gives me this warning:

headsort.c: In function `main':
headsort.c:22: warning: passing arg 4 of `qsort' from incompatible
pointer type

Anyone know why??

Code:
int strcompare(void *p1, void *p2) {
return strcmp((char *)p1, (char *)p2);
}

The qsort function is expecting (int (*)(const void *, const void *)) but
you are giving it (int (*)(void *, void *)).

Just curious, why the wrapper? Couldn't you just use:

qsort((void *)ary, (size_t)nelems, sizeof(ary[0]), strcmp);

No, and it's a FAQ: Question 13.8 at

http://www.eskimo.com/~scs/C-faq/top.html
 
B

Ben Pfaff

Just curious, why the wrapper? Couldn't you just use:

qsort((void *)ary, (size_t)nelems, sizeof(ary[0]), strcmp);

1. No, strcmp doesn't have the correct parameter types.
2. No, strcmp expects pointers to char, not pointers to pointers
to char.
 
B

Ben Pfaff

monkeys paw said:
Thanks for the info. Is there any difference between:
return strcmp(*((const char **)p1), *((const char **)p2));

-OR-

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

The former dereferences a pointer. The latter does not. Thus,
they are completely different.
 
M

Martin Ambuhl

monkeys said:
Compiling the following code gives me this warning:

headsort.c: In function `main':
headsort.c:22: warning: passing arg 4 of `qsort' from incompatible
pointer type

Anyone know why??

Try using the same qualified type that qsort expects:
Code:
int strcompare(void *p1, void *p2) {
^ ^
const const
 
B

Ben Pfaff

monkeys paw said:
int strcompare(void *p1, void *p2) {

The name "strcompare" is reserved, as are all identifiers that
begin with "str" followed by a lowercase letter. Use something
different, such as str_compare.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,999
Messages
2,570,243
Members
46,836
Latest member
login dogas

Latest Threads

Top