First of all, in modern C++ compile you can use #pragma once
instead of include guards.
Then, your example is a little confuse, because you define an extern
function in your header. Normally include
files are used to define function's declarations and not function's definitions.
If you define functions in your header and if this header is used by more than one CPP source files, this function will be define more times with same name and you will have an error when program will be linked !
A better include would be
#ifndef HEADER_FILE
#define HEADER_FILE
int two(void);
#endif
or
#ifndef HEADER_FILE
#define HEADER_FILE
static int two(void) { return 2; }
#endif
or
#pragma once
static int two(void) { return 2; }
In the last case, function two()
is defined in each CPP source files that include this header; but this function is static, so CPP sources are compiled correctly and CPP program is linked without problem.
In your question, you ask
in which case we can also forgot adding #define HEADER_FILE?
Personally, I use same header in very special tricky situation.
The following 2 includes are a "good" example:
/*******************************************************************
* XTrace.Configuration.h
********************************************************************
*/
#pragma once
#define MODULEx(n) extern StructDefineMODULE MODULE_##n;
#include "XTrace.Modules.h"
#undef MODULEx
#define MODULEx(n) { #n, &MODULE_##n } ,
static struct ModuleTRACE tModuleTrace[]
= {
#include "XTrace.Modules.h"
{ 0, 0 }
};
where XTrace.Modules.h
include is following
/*******************************************************************
* XTrace.Modules.h
********************************************************************
*/
MODULEx( BBDIXFILE )
MODULEx( CECHO )
MODULEx( INITDBFIELD )
MODULEx( IVIRLUX )
The first include contains #pragma once
and call same internal include 2 times.
The first time it is called to define extern declaration of StructDefineMODULE structure.
The second time is is called to initialize an array of ModuleTRACE structures.
Since this include is called 2 times, #pragma once
or #ifndef
must be avoid.
In using an internal include I'm sure at 100% that all elements used to define StructDefineModule are also used to initialize tModuleTrace[] array.
The include internal result, would be
/*******************************************************************
* XTrace.Configuration.h
********************************************************************
*/
#pragma once
extern StructDefineMODULE MODULE_BBDIXFILE;
extern StructDefineMODULE MODULE_CECHO;
extern StructDefineMODULE MODULE_INITDBFIELD;
extern StructDefineMODULE MODULE_IVIRLUX;
static struct ModuleTRACE tModuleTrace[]
= { { "BBDIXFILE" , &MODULE_BBDIXFILE }
, { "CECHO" , &MODULE_CECHO }
, { "INITDBFIELD" , &MODULE_INITDBFIELD }
, { "IVIRLUX" , &MODULE_IVIRLUX }
, { 0, 0 }
};
I hope that this can help you to understand why, in some situations, include guards can be avoid !