I discover that no matter how, I cannot access an array defined in an external file. So I do some simple test like these in both c and c++:
In C:
main.c
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int func();
char arr[100]="";
int main()
{
for(int i=0;i<=9;++i){
func();
printf("%s\n",arr);
}
return 0;
}
func.c
#include<string.h>
#include<stdio.h>
extern char* arr;
int func(){
strcat(arr,"hello"); // try to access arr here
return 0;
}
In C++:
main.cpp
#include<iostream>
using namespace std;
int func();
char arr[100]="";
int main()
{
for(int i=0;i<=10;++i){
func();
cout<<arr<<endl;
}
return 0;
}
func.cpp
#include<cstring>
extern char* arr;
int func(){
strcat(arr,"hello"); // try to access arr here
return 0;
}
Pretty simple test as you can see. No matter what method I use to access an array in an external file, I got segmentation fault.
Variable linking isn't type-safe.
The problem is that you're defining the name "arr" to refer to an array.
Assuming that the array is located at address 0x10, it looks something like this:
Address 0x10 0x11 0x12 0x13
Content | 0 | 0 | 0 | 0 | (... 100 zeroes in total)
The name "arr" refers to the location where this array is stored.
In "func.cpp" (and "func.c" - they work exactly the same) you claim, or declare, that the name "arr" refers to a pointer.
This is a lie because it is not what you defined it to be, but the compiler and the linker blindly trust you.
This lie causes the code in func to interpret the value stored at the address 0x10 as a pointer instead of an array.
With 32-bit pointers, that would be
Address 0x10 0x14
Content | 0 | 0 | (...)
And when you strcat onto 0, things don't go well.
If you store something more distinct than zeroes in the array (e.g. "\1\2\3\4") and examine the pointer in a debugger, it will be more obvious that the array's elements have "become" the pointer's value.
The fix is to make the proper claim; that arr is an array:
extern char arr[];
(Note that in variable declarations, as opposed to function parameters, char arr[] is not the same as char* arr.)
Use
extern char arr[];
instead of
extern char* arr;
Though an array is implicitly converted into a pointer in many situations in C, an array is not same as a pointer. What you have is a pointer, not declaration. The declaration in func.c doesn't match defintion in main.c.
simple thing is you have to use extern keyword at both the places.
in main.c
extern char arr[100]="";
and in func.c
extern char *arr;
this will tell compiler that arr is an extern variable name, so that it can be accessed in other files.