2

Suppose I have two files: file1.c- contains global definition of an int array of size 10 named "array[10]". file2.c- contains an int pointer named "extern int *array", here I am trying to link this pointer to array.

But when I check the address of array in file1.c and pointer value in file2.c, they are both different. Why it is happening?

2 Answers 2

6

That doesn't work, in file2.c, you need

extern int array[];

since arrays and pointers are not the same thing. Both declarations must have the compatible types, and int* is not compatible with int[N].

What actually happens is not specified, the programme is ill-formed with extern int *array;, but probably, the first sizeof(int*) bytes of the array are interpreted as an address.

Sign up to request clarification or add additional context in comments.

4 Comments

But what actually happens in memory? Does memory get allocated for both the array (40 bytes) and pointer (4 bytes on 32-bit)?
Undefined behaviour (ill-formed programme, actually). But probably, the first four (or eight) bytes of teh array are interpreted as an address.
ok, but linker links the pointer to an array and does not report a compile time error. To what it actually links?
It links to the symbol of the same name, that means whenever you refer to array in file2.c, the appropriate number of bytes of the array are interpreted as the value of an int*. It is quite likely that any dereferencing of that (believed) pointer leads to a crash.
0

extern1.c

#include <stdio.h>

extern int *array;
int test();

int main(int argc, char *argv[])
{
    printf ("in main: array address = %x\n", array);
    test();
    return 0;
}

extern2.c

int array[10] = {1, 2, 3};

int test()
{
    printf ("in test: array address = %x\n", array);
    return 0;
}

The output:

in main: array address = 1
in test: array address = 804a040

And the assemble code:

08048404 <main>:
 8048404:       55                      push   %ebp
 8048405:       89 e5                   mov    %esp,%ebp
 8048407:       83 e4 f0                and    $0xfffffff0,%esp
 804840a:       83 ec 10                sub    $0x10,%esp
 804840d:       8b 15 40 a0 04 08       mov    0x804a040,%edx    <--------- this (1)
 8048413:       b8 20 85 04 08          mov    $0x8048520,%eax
 8048418:       89 54 24 04             mov    %edx,0x4(%esp)
 804841c:       89 04 24                mov    %eax,(%esp)
 804841f:       e8 dc fe ff ff          call   8048300 <printf@plt>
 8048424:       e8 07 00 00 00          call   8048430 <test>
 8048429:       b8 00 00 00 00          mov    $0x0,%eax
 804842e:       c9                      leave  
 804842f:       c3                      ret    

08048430 <test>:
 8048430:       55                      push   %ebp
 8048431:       89 e5                   mov    %esp,%ebp
 8048433:       83 ec 18                sub    $0x18,%esp
 8048436:       c7 44 24 04 40 a0 04    movl   $0x804a040,0x4(%esp) <------- this (2)
 804843d:       08 
 804843e:       c7 04 24 3d 85 04 08    movl   $0x804853d,(%esp)
 8048445:       e8 b6 fe ff ff          call   8048300 <printf@plt>
 804844a:       b8 00 00 00 00          mov    $0x0,%eax
 804844f:       c9                      leave  
 8048450:       c3                      ret   

Pay attention to the <------- in the assemble code. You can see in main function the array is array[0] and in test function the array is the address.

2 Comments

In main you're not printing the address, but the value of the pointer (and in test, the value of the pointer to the first element into which the array is converted when passed to printf). If you print &address in both, you'll get the same output. Good illustration.
int* is not compatible with int[N]

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.