I am playing with example code provided in one of the answers to typedef fixed length array .
The answer only states that the code fails, but does not explain, why. Could anyone provide an explanation?
#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) {
printf("im1: %d, %d\n", b[0], b[1]);
print(&b);
printf("im2: %d, %d\n", b[0], b[1]);
}
void print(twoInts *c){
printf("pr: %d, %d\n", (*c)[0], (*c)[1]);
}
Compiling this produces the following warnings:
a.c: In function ‘intermediate’:
a.c:19:11: warning: passing argument 1 of ‘print’ from incompatible pointer type [-Wincompatible-pointer-types]
19 | print(&b);
| ^~
| |
| int **
a.c:5:21: note: expected ‘int (*)[2]’ but argument is of type ‘int **’
5 | void print(twoInts *twoIntsPtr);
| ~~~~~~~~~^~~~~~~~~~
And the output is:
pr: 0, 1
im1: 0, 1
pr: 1854416416, 32767
im2: 0, 1
What I can't understand is why the "pr" lines differ. After all - both a
and b
have type twoInts
and both produce same results when index operator ([]
) is applied.
========== UPDATE ===========
I now realize that what I'm really interested in is what the actual value (actual bytes) does the argument c
has?
Let's say we have the following memory layout:
The original array is located at memory address 150:
m[150]=0
m[154]=1
Argument b
is in stack and has (let's say) address 140. My understanding is that it has type int*
and therefore probably holds address of first element of the array:
m[140]=150 // argument b
Calling the print() from main()
will probably put the argument c
at the very same address, but I'm not sure about the value:
m[140]=? // argument c, print() is called directly from main()
Calling the print() from intermediate()
will put argument c
at even earlier address, but would the value be 140 - the address of argument b
?
m[130]=? // argument c, print() called from intermediate()