You have to use consistent types for objects declared across different translation units.
Given int a[] = {2, 3};
, either of the declarations extern int a[];
or extern int a[2]
; would be compatible whereas extern int *a;
would not as pointers and arrays are completely separate types.
The one thing special about arrays is the when the name of an array appears in any expression context other than as an operand to "address of" (unary &
) or sizeof
, they are automatically converted to a pointer to their first element. This is what provides the syntax compatibility between arrays and pointers, but they are not the same type.
Consider these two functions for a commented example. Note that the expression a
is converted to a pointer to its first element in the second (and technically third) printf
of the first function, but not in the first printf
where it is the operand to &
.
#include <stdio.h>
void print_array_info(void)
{
extern int a[];
printf("address of a: %p\n", (void*) &a); // prints address of a
printf(" converted a: %p\n", (void*) a); // prints address of a[0]
printf("value of a[0]: %x\n", a[0]); // prints value of a
}
void print_pointer_info(void) {
extern int a[];
int *b = a; // == &a[0]
printf("address of b: %p\n", (void*) &b); // prints address of b
printf(" value of b: %p\n", (void*) b); // prints value of b (== &a[0])
printf("value of b[0]: %x\n", b[0]); // prints value of b[0] (== a[0])
}
Note that I use %p
to print pointers and explicitly cast to void*
.