Reputation: 6839
As we know, we can use int (*p)[10]
to define a pointer which points to an int[10] array, so if we have p=0
and sizeof(int)==4
, p+1
will be 0+10*4 = 40
, this works because the compiler knows what p is when compiling.
And then what if we do it like this:
int main()
{
int sz = 10;
int (*p)[sz];
}
in other words, nobody would know the sz
until the program runs there. I supposed this should not be working, but it does work..
So my question is, how it works? I mean, is there any place that store a value's type in c at runtime? If not, how this could work? Of this is just compiler-related?
I am using gcc version 4.4.5 (Ubuntu/Linaro 4.4.4-14ubuntu5)
, and you can test it with the following code.
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int main()
{
int COL ;
int ROW ;
scanf("%d %d", &COL, &ROW);
int (*p)[COL];
int *mem = (int*)malloc(sizeof(int)*COL*ROW);
memset(mem,0,sizeof(int)*COL*ROW);
p = (int (*)[10])mem;
printf("0x%p\n", p);
printf("COL=%d\n", p+1, (((int)(p+1))-((int)p))/sizeof(int));
mem[2*COL+0] = 1;
printf("%d\n", p[2][0]);
mem[2*COL+5] = 2;
printf("%d\n", p[2][5]);
mem[6*COL+7] = 3;
printf("%d\n", p[6][7]);
p[1][2] = 4;
printf("%d\n", mem[1*COL+2]);
free(p);
return 0;
}
I hope I am not asking a stupid question nor making stupid mistake...
Upvotes: 2
Views: 334
Reputation: 157344
Pointer arithmetic on variable length array types is well defined per 6.5.6:10, which has example code very similar to yours. Per 6.5.3.4:2, when sizeof
is applied to a variable length array, the operand is evaluated at runtime to determine the size, so variable length array pointer arithmetic proceeds likewise.
Variable length arrays (6.7.6.2:4) have been part of the standard since the second edition (ISO/IEC 9899:1999 as amended); they are however an optional feature that conformant implementations do not have to support (6.10.8.3).
Upvotes: 2