Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Pass array to a function as a pointer and value

What is the deference between passing array this way:

static char arr[N];

void func(void *buf, size_t size) {
    // ...
}

int main(void) {
    func(arr, N);

    // ...
}

And this way:

// ...

int main(void) {
    func(&arr, N);

    // ...
}

Is there any deference in those listings? It seems that the 2nd version passes an array as void **, but is it really so?

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

The first is correct and the second is wrong or at least very questionable.

arr when used in an expression or passed to a function, gets adjusted to a pointer to the first element. So it turns equivalent to char*.

In the second example, &arr is one of the few exceptions to this "array decay" rule. Instead of a pointer to the first element, we get a pointer to the whole array, type char(*)[N]. This type is not compatible with char*, so if you would attempt to cast the void* buf to a char* inside the function, the second example causes a subtle bug.

The reason why the second example compiles at all is because void* (and only that type, not void**) is a special pointer type that can be converted to/from any other pointer to object. Should you change the function to

void func(char *buf, size_t size)

Then func(&arr, N); gives the expected compiler diagnostic "passing argument 1 of ‘func’ from incompatible pointer type".

Now as it happens, if you write the function like this

void func(void *buf, size_t size) {
    char* ptr = buf;
    for(int i=0; i<size; i++)
    {
      printf("%c ", ch[i]);
    }
}

It will most likely work for either version, because the address of the first item (char*) is the same as the address of the array (char(*)[N]). Also, C’s peculiar type system allows us to access a memory location of some type through an array or struct of items of that same type ("the strict aliasing rule").

Best practices:

  • Use the first version.
  • Avoid the use of void* when possible, since they are type unsafe.
  • Be as explicit with types as you can and don’t rely on implicit type conversions.
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading