By the answer given here, I am trying to construct a working example and try to understand behavior of the extern linkage.
Here is my example:
extern.h
extern int global_counter;
int file_counter;
extern.c
#include "extern.h"
int global_counter = 5;
incrementor1.c
#include "extern.h"
#include <stdio.h>
void incrementor1_global()
{
global_counter++;
printf("From Incrementor1...\n");
printf("Global counter is: %d\n", global_counter);
}
void incrementor1_local()
{
file_counter++;
printf("From Incrementor1...\n");
printf("File counter is: %d\n", file_counter);
}
incrementor2.c
#include "extern.h"
#include <stdio.h>
void incrementor2_global()
{
global_counter++;
printf("From Incrementor2...\n");
printf("Global counter is: %d\n", global_counter);
}
void incrementor2_local()
{
file_counter++;
printf("From Incrementor2...\n");
printf("File counter is: %d\n", file_counter);
}
You can yourself put these into separate files as depicted. Here is my main.c now:
main.c
void incrementor1_global();
void incrementor1_local();
void incrementor2_global();
void incrementor2_local();
int main(char argc, char* argv[])
{
incrementor1_global();
incrementor2_global();
incrementor1_local();
incrementor2_local();
}
Since I link .o files to my main, I am just declaring the functions and since they are extern by default, they are linked by the linker as I understood. And lastly, here is a makefile if you want to try it yourself.
CC=gcc
CFLAGS=-I.
DEPS = extern.h
OBJ = main.o extern.o incrementor1.o incrementor2.o
%.o: %.c $(DEPS)
$(CC) -c -o $@ $< $(CFLAGS)
main: $(OBJ)
gcc -o $@ $^ $(CFLAGS)
.PHONY: clean
clean:
rm -f *.o
So by the answer linked above, I think global_counter should be shared by all translation units while each should have their own copy of file_counter. But the output I get is:
From Incrementor1...
Global counter is: 6
From Incrementor2...
Global counter is: 7
From Incrementor1...
File counter is: 1
From Incrementor2...
File counter is: 2
So, I think both incrementor have a one copy of file_counter and that is a global variable. But now I don't know how I can replicate the answer given and make them have their own copy. Any suggestions?
By the way, If I want to give a definition to file_counter in extern.h, since it is included in both incrementors I am getting multiple definitions error. This confuses me further on how could I make them have a shared copy.
int file_counter
is a tentative definition and is a global variable (with external linkage), as it is defined outside of any function. It is a good practice to have variable definitions in C source files, not in headers.
If you want each translation unit to have its own copy of file_counter
, one way is to mark it as static
and define it both in incrementor1.c
and incrementor2.c
. In that case, the visibility of the variable will be restricted only to the file in which it is defined.