Should macro TEST_H not prevent multiple definitions error of num here ?
No. Each c
file or translation unit compiled separately and header guard avoids multiple definitions within transaction unit.
In preprocessing stage of compilation all header files declared in a transaction unit are copied,macro's are expanded and many more things are done. refer for more details.
Understand how header guard is working,
//test.h
#ifndef __TEST_H__
#define __TEST_H__
int num=12;
#endif
If Multiple includes of same headers,
//main.c
#include "test.h"
#include "test.h"
int main(){
}
Translates as below during per-processing stage of compilation and conditional compilation part of code will be removed.
#ifndef __TEST_H__
#define __TEST_H__
int num=12;
#endif
//as __TEST_H__ is already defined subsequent inclusion of test.h has no effect
#ifndef __TEST_H__
#define __TEST_H__
int num=12;
#endif
int main(){
}
And Hence compiler will not detect any conflict with multiple definition of num
.
Linking takes one or more object files or libraries as input and combines them to produce a single (usually executable) file. In doing so, it resolves references to external symbols, assigns final addresses to procedures/functions and variables, and revises code and data to reflect new addresses (a process called relocation). Which detects multiple instance of the same variable and throws link time error for multiple definition.
Should int num; must not be a definition of num(as it will be initialized to 0) and compiler should again show same error of multiple definitions of num?
There has to be exactly one definition of any functions or initialized global variables, but the definition of an uninitialized global variable can be treated as a tentative definition. C then allows (or at least does not forbid) different source files to have tentative definitions for the same object. (source)