简体   繁体   中英

Casting a const void * to a const char * in C

So I have a C function that goes like this:

int cmp (const void *a, const void* b)
 return rot13cmp( (const char*)a, (const char*)b );
}

and rot13cmp is another function that takes two parameters of type const char *.

I pass this function into the compare parameter for the C qsort function but it doesn't seem to work.

However, if I instead cast the const void * variables by doing

return rot13cmp ( *(const char **)a, *(const char **)b ); 

the function then starts to work. I looked this up at SO but every source said that the first method of casting should work so I wanted to know why only the second one worked for me?

Edit: Here's the relevant code I have,

int cmp (const void *a, const void *b) {
 return rot13cmp( (const char *)a, (const char *)b );
}

int rot13cmp (const char *a, const char *b) {
 while (*a == *b && *a != '\n') {
  a++;
  b++;
 }

 if (*a == *b) { return 0; }
 else if (*a == '\n') { return 1; }
 else if (*b == '\n') { return 1; }
 else { return rot13(*a) - rot13(*b);
}

and rot13 returns an int for the ASCII code of a letter rotated by 13 letters in the alphabet.

I called qsort by doing

qsort(words, word_count, sizeof(char*), cmp);

where words is an array of char** and word_count is an int. cmp is also just

qsort() calls the comparison function with pointers to the array elements that should be compared.

If your array contains const char* , that means the comparison function is called with pointers to those pointers, and you have to cast and dereference accordingly.

With (const char*)a you are interpreting the parameter as if it would be a pointer to const char . But it isn't. In reality it's a pointer to the const char* in the input array.

That's why (const char**)a is the correct cast, it interprets the parameter as a pointer to a const char* . To do string comparison you want that pointed-to const char* , which you access by dereferencing the casted value with * .

You can think of it as first correcting the type (by casting), and then accessing the pointed-to value (by dereferencing).

The difference between the two attempts is that the second case does an additional dereference. This is important since qsort() doesn't pass the const char* directly, but rather passes a pointer to it. So we have to look at the pointed-to value to find what we are looking for. By casting directly to const char* we just claim that the variable would contain such a pointer, which won't end well because that's not the case.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM