Jayram
Jayram

Reputation: 19578

Behaviour of extern in C

If I declare int Array[10]; in file1.c

In file2.c if I I have a function like this

extern int *Array;
fun()
{
    Array[0]=10; 
}

Is there any problem with this or not?

Upvotes: 1

Views: 347

Answers (2)

6502
6502

Reputation: 114539

Yes there is a problem.

You are declaring a Array to be a pointer, while instead it's an array. The two are very distinct objects and here you're basically providing false information to the compiler.

Note that the C syntax to access an element is Array[0] in both cases, but if Array is a pointer variable the machine code needed will be different from if Array is instead an array (with the pointer there is one extra indirection).

For example if Array1 is declared as extern int *Array the machine code generated by Array1[ix] += 3 by gcc is:

movslq  ix(%rip), %rax        ;; Load index value from location ix
movq    Array1(%rip), %rdx    ;; Load pointer value from location Array1
leaq    (%rdx,%rax,4), %rax   ;; Compute rax as pointer + index*4
addl    $3, (%rax)            ;; Add 3 to the location pointed by rax

If instead Array2 is declared as extern int Array2[10] the code for Array2[ix] += 3 is simply:

movslq  ix(%rip), %rax        ;; Load in rax the index value from location ix
addl    $3, Array2(,%rax,4)   ;; Add 3 to the location Array2 + index*4

As you can see in the first case there is an extra indirection and the content of the memory at address Array1 is read to find where the increment should be done in memory. In the second case instead only the index needs to be read to compute where the location to increment will be.

To make things more confusing in C an array "decays" into a pointer to the first element in many cases, so for example if you've a function expecting a pointer passing an array is fine because the compiler will take care of handling the difference.

The compiler must be told if an object in memory is an array or a pointer because the semantic is different; the code in the question instead does exactly this... one part of the program allocates an array and tells some part of the program that it's a pointer instead.

Upvotes: 8

Yu Hao
Yu Hao

Reputation: 122403

The declaration extern int *Array does not declare an array and therefore does not match the actual definition. You have to declare:

extern int Array[];

C99(ISO/IEC 9899) §6.5.7.2 Array declarators

Note the distinction between the declarations

extern int *x;
extern int y[];

The first declares x to be a pointer to int; the second declares y to be an array of int of unspecified size(an incomplete type), the storage for which is defined elsewhere.

Upvotes: 0

Related Questions