Home > Net >  C [-Wincompatible-pointer-types] how to cast
C [-Wincompatible-pointer-types] how to cast

Time:07-22

my code: https://godbolt.org/z/de7fbdjh7

code from source: https://stackoverflow.com/a/49072888/15603477
Almost exact the same.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct 
{
    int iValue;
    int kValue;
    char label[6];
} my_data;

int cmp_mydata_ivalue(my_data* item1 , my_data* item2 )
{
    if(item1->iValue < item2->iValue) return -1;
    if(item1->iValue > item2->iValue) return 1;
    return 0;
}

int main(void){
    my_data datalist[256] = {0}; 
    {
        int i;
        for(i = 0;i<20;i  ){
            datalist[i].iValue = i 100;
            datalist[i].kValue = i 1000;
            sprintf(datalist[i].label,"%2.2d", i 10);
        }
    }
    printf("new line\n");
    {
        my_data srchitem = {105,1018,"13"}; 
        
        my_data *foundItem = (my_data*) bsearch(&srchitem, datalist,20, sizeof(my_data),cmp_mydata_ivalue);
        bsearch_results(&srchitem, foundItem);
    }
}

The same question asked many times. But I don't know how to cast it.
error code:

*callback1.c: In function ‘main’:
callback1.c:58:89: warning: passing argument 5 of ‘bsearch’ from incompatible pointer type [-Wincompatible-pointer-types]
   58 |         my_data *foundItem = (my_data*) bsearch(&srchitem, datalist,20, sizeof(my_data),cmp_mydata_ivalue);
      |                                                                                         ^~~~~~~~~~~~~~~~~
      |                                                                                         |
      |                                                                                         int (*)(my_data *, my_data *) {aka int (*)(struct <anonymous> *, struct <anonymous> *)}*

One way to try to use gcc option to supress the error. Another way is somewhere I need to cast. But now i don't know how to cast.

Tutorial I found so far: https://www.tutorialspoint.com/c_standard_library/c_function_bsearch.htm

CodePudding user response:

The comparison function must have the type

int ( const void *, const void * )

See the declaration of the function bsearch

void *bsearch(const void *key, const void *base,
              size_t nmemb, size_t size,
              int (*compar)(const void *, const void *));

So you should declare and define your function like

int cmp_mydata_ivalue( const void *a , const void *b )
{
    const my_data *item1 = a;
    const my_data *item2 = b;
    if ( item1->iValue < item2->iValue) return -1;
    if(item1->iValue > item2->iValue) return 1;
    return 0;
}

CodePudding user response:

Don't ever use workarounds to suppress errors/warnings from the compiler. You should carefully understand them and fix the code instead. If you chose to ignore them, you must be very conscious of what are the implications.

Having said that, the bsearch prototype is the following:

void* bsearch( const void *key, const void *ptr, size_t count, size_t size,
               int (*comp)(const void*, const void*) );

meaning it expects the last parameter to be a function pointer to a function with the following signature:

int function(const void*, const void*);

What you are passing is a function of this kind

int cmp_mydata_ivalue(my_data* item1 , my_data* item2 )

Which is uncompatible, as C can't do any implicit cast. You must rewrite your function to something like this:

int cmp_mydata_ivalue( const void *cvp_item1 , const void *cvp_item2 )
{
    const my_data *item1 = (const my_data *)cvp_item1;
    const my_data *item2 = (const my_data *)cvp_item2;
}
  • Related