How are array and pointer types handled internally in C compilers? ( int *a; vs. int a[]; )
arrays, c, language-lawyer, pointers
Solution
Are a and b the same type? Is int *a handled as the same type as int a[] internally in the compiler?
From the `comp.lang.C` FAQ:
... whenever an array appears in an expression, the compiler implicitly generates a pointer to the array's first element, just as if the programmer had written &a[0]. (The exceptions are when the array is the operand of a sizeof or & operator, or is a string literal initializer for a character array...)
... Given an array a and pointer p, an expression of the form a[i] causes the array to decay into a pointer, following the rule above, and then to be subscripted just as would be a pointer variable in the expression p[i] (although the eventual memory accesses will be different ...
Given declarations of
char a[] = "hello";
char *p = "world";
... when the compiler sees the expression `a[3]`, it emits code to start at the location `a`, move three past it, and fetch the character there. When it sees the expression `p[3]`, it emits code to start at the location `p`, fetch the pointer value there, add three to the pointer, and finally fetch the character pointed to. In other words, `a[3]` is three places past (the start of) the object named `a`, while `p[3]` is three places past the object pointed to by `p`.
Emphasis is mine. The biggest difference seems to be that the pointer is fetched when it's a pointer, while there is no pointer to fetch if it's an array.
Problem
I need a language lawyer with authoritative sources. Take a look at the following test program which compiles cleanly under gcc: ``` #include <stdio.h> void foo(int *a) { a[98] = 0xFEADFACE; } void bar(int b[]) { *(b+498) = 0xFEADFACE; } int main(int argc, char **argv) { int a[100], b[500], *a_p; *(a+99) = 0xDEADBEEF; *(b+499) = *(a+99); foo(a); bar(b); printf("a[98] == %X\na[99] == %X\n", a[98], a[99]); printf("b[498] == %X\nb[499] == %X\n", b[498], b[499]); a_p = a+98; *a_p = 0xDEADFACE; printf("a[98] == %X\na[99] == %X\n", a[98], a[99]); } ``` It produces the output I expect: ``` anon@anon:~/study/test_code$ gcc arrayType.c -o arrayType anon@anon:~/study/test_code$ ./arrayType a[98] == FEADFACE a[99] == DEADBEEF b[498] == FEADFACE b[499] == DEADBEEF a[98] == DEADFACE a[99] == DEADBEEF ``` Are a and b the same type? Is `int *a` handled as the same type as `int a[]` internally in the compiler? From a practical point of view `int a[100], b[500], *a_p, b_a[];` all seem to be the same type. It's hard for me to believe that the compiler is constantly adjusting these types in the various circumstances in my above example. I'm happy to be proven wrong. Can someone settle this question for me definitively and in detail ?