Q:

runtime datatype working in c, how does sizeof work?

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...

A:

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).

