Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

casting pointer to pointer to an array

Tags:

c

Below is the code snippet. I want to know if line no. 17 typecasting is valid and proper in c?

#include <stdio.h>

typedef int twoInts[2];

void print(twoInts *twoIntsPtr);
void intermediate (twoInts twoIntsAppearsByValue);

int main () {
    twoInts a;
    a[0] = 0;
    a[1] = 1;
    print(&a);
    intermediate(a);
    return 0;
}
void intermediate(twoInts b) {
    print((int(*)[])b); // <<< line no. 17 <<<
}

void print(twoInts *c){
    printf("%d\n%d\n", (*c)[0], (*c)[1]);
}

Also, when i change the definition intermediate to

void intermediate(twoInts b) {
    print(&b);
}

I am getting below warnings while compiling and o/p is not proper.

1.c:17:11: warning: passing argument 1 of print from incompatible pointer type
     print(&b);
           ^
1.c:5:6: note: expected int (*)[2] but argument is of type int **
 void print(twoInts *twoIntsPtr);

As per my understanding, array is decaying to pointer to int in funtion argument. What is the exact reason?

like image 990
Jagdish Avatar asked Oct 19 '22 00:10

Jagdish


1 Answers

a is an array. So when you pass it to intermediate(), it gets converted into a pointer to its first element (aka "array decaying").

So, the b in:

void intermediate(twoInts b) {
    print(&b);
}

has type int*, not int[2] as you might seem to expect. Hence, &b is of type int** rather than int (*)[2] that's expected by print() function. Hence, the types don't match.

If you change intermediate() to:

void intermediate(twoInts *b) {
    print(b);
}

then you wouldn't need to pass the address of the &b and it will as expected and the types would match correctly.

like image 162
P.P Avatar answered Nov 03 '22 00:11

P.P