Say I have a header file file which contains a struct.
Struct aa
{
int a;
int b;
};
In a.c
file I include that header file and I do
struct aa first;
and then use first.a
and first.b
to make changes.
In b.c
file I include that header file and I do
struct aa first;
and then use first.a
and first.b
to make changes.
Can I do whatever I did in b.c
? How is linkage done? Does it overwrite the values? How does it work?
Or should I use extern anywhere ?
If you write struct aa first;
in a function,
// a.c
#include "your_header.h"
void foo(void)
{
struct aa first;
first.a = 18;
first.b = 19;
...
}
// b.c
#include "your_header.h"
void bar(void)
{
struct aa first;
first.a = 21;
first.b = 22;
...
}
then the variable is a local variable of foo
and bar
respectively, they
happen to have the same name, but are not the same variable. So the
initialization of first
in bar
does not affect in any way the variable
first
in foo
.
If you however want a global variable so that the different compile units (meaning
different .c
files) like a.c
and
b.c
can access to, then you need to declare the variable as extern
in the
header and define it in either a.c
or b.c
.
// your_header.h
#ifndef YOURHEADER_H
#define YOURHEADER_H
struct aa {
int a;
int b;
};
// the "extern" tells the compiler that the
// variable might be defined somewhere else,
// it it's not in the current compile unit,
// it won't give you an error.
extern struct first;
#endif
// a.c
#include "your_header.h"
// a.c defines in this compile unit the global
// variable. This information is important for the linker as well
struct first;
void foo(void)
{
first.a = 10;
first.b = 11;
}
//b.c
#include "your_header.h"
void bar(void)
{
first.a = 100;
first.b = 200;
}
Now when you compile a.c
: gcc a.c -c -o a.o
, the compiler knows from the
header file that first
is a global variable that may be defined in another
compile unit. In this case it is defined in a.c
itself.
Now when you compile b.c
: gcc b.c -c -o b.o
, the compiler knows from the
header file that first
is a global variable that may be defined in another
compile unit. It is not defined in b.c
, so the compiler will let the linker
deal with this.
When you link your program: gcc a.o b.o othermodules.o -o myprogram
, the
linker will know in which object file the variable first
was defined and will
create the correct offsets for when the program access this variable.
In this case, if you do this in main
.
#include "your_header.h"
#include "other_headers.h"
int main(void)
{
foo();
bar();
}
then bar
will override the values of first.a
and first.b
that were set in foo
,
because first
is a global variable.