Is it possible create a "variable" header guard name in C? - c

fellow programmers,
I'm new to the C preprocessor and have been recently trying to create a generic-like library in C (as an exercise), and I've come upon a little problem when creating header guards.
All the preprocessor macros are set up so I can include and use my headers like this:
#define TYPE int
#include "myheader.h"
#undef TYPE
#define TYPE float
#include "myheader.h"
#undef TYPE
int main(void){
//Do stuff
MyFunc_int();
//More stuff
MyFunc_float();
return 0;
}
But the problem appears when I need to include the headers in more than one file. Header guards are usually applied in this case, but since the header can be included once -for each type-, neither the usual construction nor #pragma once can be used.
My question then is: Is it possible to create a "variable" header guard to work for different TYPE definitions?

When you want to include the header from various compilation units, you could divide the header into a publich part that plays the role of the header and a private part that plays the role of a *.c file, for example:
#define M_CONCAT(a, b) a##b
TYPE M_CONCAT(TYPE, _min)(TYPE a, TYPE b);
#ifdef IMPLEMENT
TYPE M_CONCAT(TYPE, _min)(TYPE a, TYPE b)
{
return (a < b) ? a : b;
}
#endif /* IMPLEMENT */
Then you can include this header from multiple files, but you have to make sure that only one file defines IMPLEMENT before including the header:
#define IMPLEMENT // only in one file
#define TYPE float
#include "myheader.h"
#undef TYPE
#define TYPE int
#include "myheader.h"
#undef TYPE
This file could be a separate compilation unit, myheader.c. You must take care to implement the function for all types, however. (But the linker will tell you, which types you've missed.)

I suggest:
Remove the #include guards in myheader.h.
Create different header files for each TYPE.
intheader.h:
#pragma once
#define TYPE int
#include "myheader.h"
#undef TYPE
floatheader.h:
#pragma once
#define TYPE float
#include "myheader.h"
#undef TYPE
And then use:
#include "intheader.h"
#include "floatheader.h"
int main(void){
//Do stuff
MyFunc_int();
//More stuff
MyFunc_float();
return 0;
}

I think you're looking for something like this:
#if !defined HEADERGUARD && defined (TYPE==int)
#define HEADERGUARD
<stuff>
#endif
You may want to have HEADERGUARD_int and HEADERGUARD_float, depending on what you're doing inside the *.h file. More conventionally, people will break it into two *.h files.

Related

C header file #ifndef #include error

I'm trying to figure out, how to use C headers with #ifndef and #include.
Lets say I have these two header files:
headerA.h:
#ifndef HEADERA_H
#define HEADERA_H
#include "headerB.h"
typedef int MyInt;
TFoo foo;
... some other structures from headerB.h ...
#endif
headerB.h
#ifndef HEADERB_H
#define HEADERB_H
#include "headerA.h"
typedef struct foo{
MyInt x;
} TFoo;
#endif
headerA.c
#include "headerA.h"
... some code ...
headerB.c
#include "headerB.h"
... some code ...
When compiling headerB.c, it says
In file included from headerB.h,
from headerB.c:
headerA.h: error: unknown type name ‘MyInt’
I think, it's becouse when headerB.h is compiling, it defines HEADERB_H and then, when headerA.h wants to include headerB.h, the #ifndef HEADERA_H is false = skips including.
What is the best practice here? I just read, that best practice is to do all #include directives in header files, but in this situation it looks like a problem.
EDIT: Ok, sorry for misleading you. This is just and example from bigger project with more files.
You have a circular dependency. Header file headerA.h depends on headerB.h which depends on headerA.h and so on and on.
You need to break that dependency, for example by not including headerB.h in headerA.h. It's not needed (nothing in headerA.h needs anything from headerB.h).
If you have to include headerB.h (as stated in your recent edit) then you first should reconsider how you use your header files, and what definition you place where. Perhaps move the definition of MyInt to headerB.h? Or have more header files, like one for type-aliases (like your MyInt which I personally see no use for), one for structures and one for variable declarations?
If that's not possible then you could try by changing the order of definitions and the include, like
#ifndef HEADERA_H
#define HEADERA_H
// Define type alias first, and other things needed by headerB.h
typedef int MyInt;
// Then include the header file needing the above definitions
#include "headerB.h"
TFoo foo;
... some other structures from headerB.h ...
#endif
Just drop the line
#include "headerB.h"
from file headerA.h

What exactly do C include guards do?

Let's say I have a header file "header.h" with a function definition.
#ifndef HEADER_FILE
#define HEADER_FILE
int two(void){
return 2;
}
#endif
This header file has an include guard. However, I'm kind of confused as to what #define HEADER_FILE is actually doing. Let's say I were to forget the include guard, it would have been perfectly legal for me to completely ignore adding '#define HEADER_FILE'.
What exactly are we doing when we define HEADER_FILE? What are we defining? And why is it okay to forget the include guard in which case we can also forgot adding #define HEADER_FILE?
It's a preprocessor macro.
All of it is preprocessor syntax, that basically says, if this macro has not already been defined, define it and include all code between the #ifndef and #endif
What it accomplishes is preventing the inclusion of file more than once, which can lead to problems in your code.
Your question:
And why is it okay to forget the include guard in which case we can also forgot adding #define HEADER_FILE?
It's OK to forget it because it's still legal C code without it. The preprocessor processes your file before it's compiled and includes the specified code in your final program if there's no logic specifying why it shouldn't. It's simply a common practice, but it's not required.
A simple example might help illustrate how this works:
Your header file, header_file.h we'll say, contains this:
#ifndef HEADER_FILE
#define HEADER_FILE
int two(void){
return 2;
}
#endif
In another file (foo.c), you might have:
#include "header_file.h"
void foo() {
int value = two();
printf("foo value=%d\n", value);
}
What this will translate to once it's "preprocessed" and ready for compilation is this:
int two(void){
return 2;
}
void foo() {
int value = two();
printf("foo value=%d\n", value);
}
All the include guard is accomplishing here is determining whether or not the header contents between the #ifndef ... and #endif should be pasted in place of the original #include.
However, since that function is not declared extern or static, and is actually implemented in a header file, you'd have a problem if you tried to use it in another source file, since the function definition would not be included.
You prevent the file from being included more than once, here
#ifndef HEADER_FILE
you test if HEADER_FILE is NOT defined, in case that's true then
#define HEADER_FILE
would define it, now if you include the file in another file, the first time it will define HEADER_FILE, while the second time, it will be already defined and hence the content of the file is not included again, since the #ifndef HEADER_FILE will be false.
Remember that these are evaluated by the preprocessor before actual compilation is done, so they are evaluated at compile time.
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 !

mutual inclusion of header files with global variables

I have a number of modules in a C program for a microcontroller not running any OS. Each module has its own type definitions, enumerations, and data structre definitions to represent the module's status and I think it would be neat to define them in the module's associated header file.
Then, I have a global variable defined in global_var.c to "remember" the current status of the whole system. Since the modules' data structures are being referred to in the global variable's definition, all the module headers are being included in global_var.h.
However, these modules will also need to access the global variable thus they will need to include global_var.h as well.
How can I avoid mutual inclusion of the header files if I really want to keep my global variable?
Many thanks!
global_var.h
#ifndef GLOBAL_VAR_H
#define GLOBAL_VAR_H
#include "module.h"
typedef struct GLOBAL_STRUCTURE {
module_structure m;
} global_structure;
#endif
global_var.c
#include "global_var.h"
global_structure gs;
module.h
#ifndef MODULE_H
#define MODULE_H
typedef struct MODULE_STRUCTURE {
int a;
} module_structure;
void module_function(void);
#endif
module.c
#include "global_var.h"
extern global_structure gs;
void module_function(void) {
gs.m.a=0;
}
I think the C language is supposed to share a global defined twice. but it depends on the compiler (well linker) as to whether your toolchain actually does that I have had some that do and some that dont. The safest route is to only declare the variable once and everywhere else explicitly declare it as extern. You will often see this done like this:
common.h
#ifundef HELLO
#define HELLO
#endif
HELLO unsigned int myglobx;
one.c
#include "common.h"
two.c
#include "common.h"
three.c
#define HELLO extern
#include "common.h"
Try this:
In Module.c
#define XYZ
then in Module.h
#define MODULETYPE
#ifdef XYZ
MODULETYPE
#else
MODULETYPE extern
#endif
MODULETYPE int var1,var2;
Do this for every module and include your header wherever you want.

Multiple inclusion of header file error in C

So I have a header file let's say "header.h" which is protected as follows:
#ifndef __HEADER1_H
#define __HEADER1_H
//type and function def
typedef struct
{
float r; //process noise
float k; //process gain
}state_t;
int get_state(state_t* state, float b);
#endif
Now I have two other headers which I defined as follows:
#ifdef __HEADER2_H
#include "header.h"
//function def
#endif
Second header:
#ifdef __HEADER3_H
//function
//the reason it is done this way is for cnditional compiling such that if the caller
//defines __HEADER3_H t this file won't be included.
#include "header.h"
#endif
Now as I suspected the compiler complained that types and functions defined in header.h were not detected in the source implementation of header2 and header3. So I included header.h in the source files as well. Now the linker is complaining functions that are defined in header.h are multiply defined.
My understanding was since the header.h is protected by ifndef it will only be included once so I don't see the problem.
here is the error that I am getting:
Symbol get_state multiply defined(by kalman.o and dsp.o)
Is there any chance that I am doing something unusally wrong?
#ifndef __HEADER1_H
#define __HEADER_H
The problem is your guard (__HEADER_H) is different from what you are checking for (__HEADER1_H). Make these both the same value.
The typical "guard" for a header file is:
myheader.h:
#ifndef _MYHEADER
#define _MYHEADER
<do stuff>
#endif
Optionally where myheader.h is included, you can do:
#ifndef _MYHEADER
#include "myheader.h"
#endif
This is optional and basically is only to improve compile performance.

Using C, one code, multiple headers if/else?

I have one piece of code that I can use for the same function on different sets of data which are defined in different header files . These header files may have the same variable defined differently.
I can pass a parameter to the code when I call it to specify which dataset I want to perform the function on.
What I would like to do is pass this parameter to the code where if the parameter equals X then I use headerX, or if parameter equals Y I use headerY.
It is my understanding that header files must be included before MAIN. Is it possible to include the header file after MAIN so that I can write an if/else statement to determine which header file I am calling?
If I can't do that then please help me figure this out.
You could use #ifdef - blocks to determine which data set you'd want to use before compiling. But if you wanted a different data set, you would need to change (recompile) the executable by changing that define.
Otherwise you would need to compile in C++ as straight C does not support overloaded functions.
Simply put, you just can't. You may be able to include headers before hand based on a condition. Just use #if-def blocks at the top of the file.
But you can't include it like if else:
This is WRONG
if(x == 1)
#include "header1.h"
else
#include "header2.h"
But you can do this at the top of the file:
#if SYSTEM_1
#include "system_1.h"
#elif SYSTEM_2
#include "system_2.h"
#elif SYSTEM_3
#include "system_3.h"
#endif
Or you could just use C++ which does support overloaded functions.
You can do simple metaprogramming by using the macro preprocessing phase. Create a "interface_myFunc.h" with something like
#define FUNCNAME(T) myFunc_ ## T
void FUNCNAME(theType)(theType t);
Create a "implement_myFunc.h" file with something like
void FUNCNAME(theType)(theType t) {
// do something with t
}
and then include this file in another file "myFunc.h"
#define theType toto
#include "interface_myFunc.h"
#undef theType toto
#define theType tutu
#include "interface_myFunc.h"
#undef theType tutu
and similar for the definitions, "myFunc.c"
#define theType toto
#include "implement_myFunc.h"
#undef theType toto
#define theType tutu
#include "implement_myFunc.h"
#undef theType tutu
Modern C, C11, also has ways to create a common interface for all these functions that you create by so-called type generic macros:
#define myFunc(X) \
_Generic((X), \
toto: FUNCNAME(toto), \
tutu: FUNCNAME(tutu) \
)(X)

Resources