虽然您可以隐式地将char*转换为void*,但对于具有这些类型的函数指针(不带警告),您不能执行相同的操作.编译器对函数签名的类型匹配更加小心.
更不用说在qsort中发生的事情恰恰相反:也就是说,void*将被转换为numcmp中的char*和strcmp中的const char*.
编译器应该在这些情况下发出警告.如果你真的必须使用一个与参数类型不同的函数,也许你应该使用一个匹配类型的包装函数,然后在调用原始函数时进行适当的显式转换.
例如:
static int strcmp_wrapper(void* s1, void* s2) { return strcmp((char*)s1, (char*)s2); } static int numcmp_wrapper(void* n1, void* n2) { return numcmp((char*)n1, (char*)n2); } qsort((void **) lineptr, 0, nlines-1, (numeric ? numcmp_wrapper : strcmp_wrapper));
qsort的现代签名是
void qsort(void *base, size_t nel, size_t width, int (*compar)(const void *, const void *));
问题const
似乎没有在您的问题中发挥作用,但K&R没有const
.
虽然您可以隐式地将char*转换为void*,但对于具有这些类型的函数指针(不带警告),您不能执行相同的操作.编译器对函数签名的类型匹配更加小心.
更不用说在qsort中发生的事情恰恰相反:也就是说,void*将被转换为numcmp中的char*和strcmp中的const char*.
编译器应该在这些情况下发出警告.如果你真的必须使用一个与参数类型不同的函数,也许你应该使用一个匹配类型的包装函数,然后在调用原始函数时进行适当的显式转换.
例如:
static int strcmp_wrapper(void* s1, void* s2) { return strcmp((char*)s1, (char*)s2); } static int numcmp_wrapper(void* n1, void* n2) { return numcmp((char*)n1, (char*)n2); } qsort((void **) lineptr, 0, nlines-1, (numeric ? numcmp_wrapper : strcmp_wrapper));
qsort的现代签名是
void qsort(void *base, size_t nel, size_t width, int (*compar)(const void *, const void *));
问题const
似乎没有在您的问题中发挥作用,但K&R没有const
.