Robert777
Robert777

Reputation: 801

Swapping 2 string pointers with a function whose parameters are void **

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

Answers (3)

user529758
user529758

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

Grijesh Chauhan
Grijesh Chauhan

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

Shade
Shade

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

Related Questions