Reputation: 801
The following code doesn't compile:
void swap(void **p, void **q) {
void *tmp;
tmp = *p;
*p = *q;
*q = tmp;
}
int main(void) {
char *s[] = {"help" , "please"};
swap(&s[0], &s[1]);
return 0;
}
While this code compiles and runs just fine:
void swap(void **p, void **q) {
void *tmp;
tmp = *p;
*p = *q;
*q = tmp;
}
int main(void) {
char *s[] = {"help" , "please"};
swap((void **) &s[0], (void **) &s[1]);
return 0;
}
Why is the casting necessary ?
Upvotes: 2
Views: 505
Reputation:
Yeah, so in addition to the already existing answers that point out that void **
is not the same as char **
: your code invokes undefined behavior because of the incompatible pointer types. Here's what you actually want:
void swap(void *p1, void *p2, size_t size)
{
unsigned char buf[size];
memcpy(buf, p1, size);
memcpy(p1, p2, size);
memcpy(p2, buf, size);
}
And call it like this:
const char *s[] = { "help", "please" }; // also note the use of `const' for string literals
swap(&s[0], &s[1], sizeof(s[0]));
Upvotes: 3
Reputation: 58271
You have incompatible pointer assignment error in first code. In C type of a string literal is char[N]
Where N is number of chars. Note in most of expressions char[N]
easily decays into char*
According to your declaration char *s[] = {"help" , "please"};
type of s[i]
is char*
(actaully char[N]
decayed into char*
).
When you pass &s[i]
then you are passing char**
that is incompatible with void**
. Second code works because you typecast into void**
in function calling.
void*
can be assigned any address type but its void**
that has to be assigned address of void*
type variable.
If you only having array of strings then in first version of swap function you can replace void
by char
then you can all without typecast.
Upvotes: 1
Reputation: 785
The casting makes the example compile because of what you are passing the function.
char *var[];
is in many ways the same as char **var;
With that being said, you are passing the function a reference/address one of the members of the array (s[0]
).
Another more prominent issue, is that the function accepts void pointers, and is passed character pointers (without the casting).
Upvotes: 0