Search code examples
arrayscpointersimplicit-conversiondereference

Why sending an array as an actual parameter to function which expects a pointer to an array needs dereferencing 2 times to access the array?


#include<stdio.h>
int fun(int (*x)[3]) {
    return **x*2; // Why we need to dereference two times here?
}
int main(void) {
    int a[3] = {1, 2, 3};
    printf("%d", fun(a)); // 2
}

So what I know is that the array name acts as an address of the array only, and in the function the x is also expecting an address of the array so why we need to dereference the x two times and not one?


Solution

  • For starters in this call

    printf("%d", fun(a));
    

    the expression a (the array designator) is implicitly converted to pointer to the element type that is has the type int *.

    At the same time the function parameter has the type int ( * )[3].

    There is no implicit conversion from the type int * to the type int ( * )[3]. So the compiler shall issue an error.

    The function call must look like

    printf("%d", fun( &a ));
    

    Within the function dereferencing the pointer x you will get an object of the type int[3] that is lvalue of the original array. Again used in expressions (with rare exceptions) the array designator is converted to the pointer of the type int * that points to its first element.

    So to access this first element of the array you need to dereference the expression one more

    **x*2
    

    You have the following chain of conversions of expressions

    &a -> int ( *x )[3]
    
    *x -> int[3]
    
    int[3] -> int *
    
    *( int * ) -> int