Is it possible to #Include in a "diamond inheritance" structure? - c

I'm trying to make some project in C.
I would like to know if it is possible to make #include from the same file twice, in a way that recalls diamond heritage.
i.e.
in a.c there is #include "a.h"
in b.c there is #include "b.h"
in b.h there is #include "a.h"
Is it possible to #include "b.h" in a.c?
I get an error:
some_variable already defined in a.obj

Simple: don't define variables in headers, just declare them:
Header:
// a.h
#ifndef A_H // always use #include guards
#define A_H
extern int my_variable; // declare my_variable
...
#endif
Source file a.c:
// a.c
#include "a.h"
int my_variable; // define my_variable
...
Source file b.c:
// a.c
#include "a.h"
#include "b.h"
...
As others have mentioned, #include guards are useful, and a good habit to get into, but they are probably not the solution for this specific problem.

You have to declare extern the variables in a.h, then modify your header a.h in the following way:
#ifndef a_h
#define a_h
//your a.h
#endif

Related

including header files in one another

if I have two header files
a.h and b.h
can I include "a.h" in b.h
and also include "b.h" in "a.h" ?
You can, but it's not a very good idea. If you really must, you can prevent recursion with the use of include guards (which are a good idea regardless).
In a.h:
#ifndef A_H
#define A_H
#include "b.h"
#endif
and b.h
#ifndef B_H
#define B_H
#include "a.h"
#endif
No that won't work. The preprocessor just replaces your #include"xyz.h" with the actual file, so this would end in an endless recursion.

How to include a header privately in C

How to include a header file in c privately so that files that include the file that includes the header wont include the header.
for example:
main.c
#include "main.h"
main.h
#include "test.h"
// I want main.c not to include test.h
I would like to know how to do that
use a #define:
in main.c
// the define MUST be before main.h inclusion
#define IN_MAIN_C
#include "main.h"
in main.h
#ifndef IN_MAIN_C
#include "test.h"
#endif

How can I avoid redefinition of types while including multiple header files?

I'm working on recompiling a C project and I'm not sure how do I fix this problem in a right way.
Here is a situation -
a.h
#ifndef A_H
#define A_H
typedef int INT;
// other variables and function definition
#endif
b.h
#ifndef B_H
#define B_H
typedef int INT;
// other variables and function definition
#endif
main.c
#include "a.h"
#include "b.h"
int main()
{
INT i = 10;
return 0;
}
The error I get in Linux with gcc:
In file included from ./main.c,
./b.h:<linenumber>: error: redefinition of typedef ‘INT’
a.h.h:<linenumber>: note: previous declaration of ‘INT’ was here
I have to include both headers due to other variables and functions. I haven't written this code, but this seems to compile in my Solaris environment which is strange. What can I do to fix this ?
Probably the native compiler on Solaris accepts that you can redefine a typedef (probably provided that the new typedef is identical to the previous one which is the case here).
I'd introduce another header file mytypes.h like this:
mytypes.h
#ifndef MYTYPES_H
#define MYTYPES_H
typedef int INT;
#endif
Include mtypes.h whereever INT is used, possibly even in main.c:
a.h
#ifndef A_H
#define A_H
#include "mytypes.h" // can be removed if INT is not used in a.h
// other variables and function definition
#endif
b.h
#ifndef B_H
#define B_H
#include "mytypes.h" // can be removed if INT is not used in b.h
// other variables and function definition
#endif
main.c
#include "a.h"
#include "b.h"
#include "mytypes.h" // not really necessary because it's already included
// via a.h and b.h, but still good practice
int main()
{
INT i = 10;
return 0;
}
If you are allowed to change the library code or compiler options then Michael Walz's answer is the way to go
In the unfortunate case that it's not changeable then it can be worked around by renaming before including the header then undefine it
#define INT INT_A
#include "a.h"
#undef INT
#define INT INT_B
#include "b.h"
#undef INT
Now just use INT_A for all the interfaces in a.h instead of INT. Same to INT_B in b.h

C preprocessor #error in header file included in multiple source files

I have two source files, main.c and datamgr.c - and two header files, config.h and datamgr.h
The testing system we're using expects these files, and only these files.
main.c:
#include "datamgr.h"
#include "config.h"
int main() {
custom_type a = 1;
a = foo();
return 0;
}
datamgr.c:
#include "datamgr.h"
#include "config.h"
custom_type foo() {
custom_type a = 1;
return a;
}
datamgr.h:
#ifndef DATAMGR_H
#define DATAMGR_H
#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>
custom_type foo();
#endif
config.h:
#ifndef CONFIG_H
#define CONFIG_H
#ifndef SET_MAX_TEMP
#error "Max temperature not set."
#endif
#ifndef SET_MIN_TEMP
#error "Max temperature not set."
#endif
typedef custom_type uint16_t
#endif
Now, the problem is that I can only define SET_MAX_TEMP and SET_MIN_TEMP in main.c, but both main.c and datamgr.c need both the header files. So if I leave them undefined in datamgr.c I get a compiler error. However, if I do define them in datamgr.c and later overwrite them in main.c, I get a different compiler error.
Please, any assistance as to how to get this horrible setup to work would be greatly appreciated.
You can pass these defines directly while compiling:
gcc -DSET_MAX_TEMP -DSET_MIN_TEMP <your files>
In datamgr.c do:
#define SET_MAX_TEMP
#define SET_MIN_TEMP
#include "datamgr.h"
#include "config.h"
#undef SET_MAX_TEMP
#undef SET_MIN_TEMP
In a comment, you said:
Because main.c is the file that our testing system uses to implement the test scenarios.
In that case, make sure that the testing system defines those macros in the command line of the compiler for every file being compiled.

How to have the compiler put a header file in a source file

I know you can put a header file on top of a file by using the -include compiler flag in gcc, but is it possible to include the header file at the end of other header file declarations of a file. So for example, I have the following declarations in a C source file.
#include "a.h"
#include "b.h"
I would like it, to become
#include "a.h"
#include "b.h"
#include "inserted.h"
rather than
#include "inserted.h"
#include "a.h"
#include "b.h"
Use
-include a.h -include b.h -include inserted.h
Add header protection to all *.h files (which should be there anyway ... ;-).
You can't do exactly what you are asking. There is no way to tell the compiler to insert a header file at a random point in a file. But maybe you can get something close.
First make all the declarations in inserted.h as a macro:
#define DECLARE_INSERTED_H \
int gFoo = 0; \
void functionBar(); \
Then in your c file:
#include a.h
#include b.h
#ifndef DECLARE_INSERTED_H
#define DECLARE_INSERTED_H
#endif // !DECLARE_INSERTED_H
DECLARE_INSERTED_H
Then compile with -i inserted.h

Resources