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.
Related
I've wrote some code but when it's in a single file I find the code overwhelming and so I've tried to seperate the code into 3 files. The first being the main section (SACode.c), the second for making a char/string dictionary (CharCharStarArray.h) and the last for storing constants (constants.h). The SACode needs to be able to access CharCharStarArray.h and constants.h. and so I've used the following code in SAcode.c
/* File CharCharStarArray.h*/
#ifndef CharCharStarArray.h
#include "CharCharStarArray.h"
/* File constants.h*/
#ifndef constants.h
#include "constants.h"
//more code
#endif
#endif
The header file CharCharStarArray.h also needs to access the constants.h file and so in the CharCharStarArray.h file I've included this snippet
#ifndef constants.h
#include "constants.h"
//more code
#endif
When compiled I get "redefinition" or "previously defined here" errors from the constants.h file
I've commented out the include constants code in the SAcode file and it compiles but this seems like bad practice. If I didn't include the CharCharStarArray.h file then SACode.c wouldn't be able to access the constants file
Here's a recreation of the problem
headefiles
#ifndef header1.h
#include "header1.h"
#ifndef header2.h
#include "header2.h"
void setup() {
// put your setup code here, to run once:
}
void loop() {
// put your main code here, to run repeatedly:
}
/*header2*/
#endif
/*header1*/
#endif
header1.h
#ifndef header2.h
#include "header2.h"
int header1var = 5;
#endif
header2.h
int header2var = 3;
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.
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.
I'm writing an embedded C program in eclipse with gcc and can't see how to get around a certain issue. I have a typedef in a header file which is protected by an include guard. Since I use this typedef in multiple headers, I need to include it in other headers, however when I try to compile, no matter what I do, one of the headers cannot see the typedef and complains of an unknown type name.
I believe this illustrates the problem:
header a.h:
#ifndef _a_h
#define _a_h
typedef enum {
USBD_OK = 0,
USBD_BUSY,
USBD_FAIL,
}USBD_Status;
#endif
header b.h:
#ifndef _b_h
#define _b_h
#include "a.h"
extern USBD_Status USB_getStatus(void);
#endif
header c.h:
#ifndef _c_h
#define _c_h
#include "a.h"
extern USBD_Status USBD_Sync(void);
#endif
This always seems to result in the error "unknown type name 'USBD_Status'" as whichever header is compiled second cannot see the typedef. Removing the include guard from a.h results in the complaint that USBD_Status is being redeclared.
edit:
I have double checked all include paths, all includes, all file names and all include guards - there are no duplicates or typos.
It could be that you have another header that uses the same header guard name.
You could add some code to the top of your a.h that does this:
#ifdef _a_h_
#error this header is already defined
#endif
This way you can track down everywhere that a.h is included and see where any oddities may occur.
As stated in the comments, your above example works so the problem must lie somewhere else ...
So I'm still getting used to modular programming, and want to make sure I'm adhering to best practices. If I have the two module header files below, will the the headers #included by each file (for example "mpi.h") be included multiple times? Is there a proper way to account for this?
Also, my module headers typically look like these examples, so any other criticism/pointers would be helpful.
/* foo.h */
#ifndef FOO_H
#define FOO_H
#include <stdlib.h>
#include "mpi.h"
void foo();
#endif
and
/* bar.h */
#ifndef BAR_H
#define BAR_H
#include <stdlib.h>
#include "mpi.h"
void bar();
#endif
And use the sample program:
/* ExampleClient.c */
#include <stdlib.h>
#include <stdio.h>
#include "mpi.h"
#include "foo.h"
#include "bar.h"
void main(int argc, char *argv[]) {
foo();
MPI_Func();
bar();
exit(0)
}
What do you mean by 'include'? The preprocessor statement #include file copies the contents of file and replaces the statement with these contents. This happens no matter
If by 'include' you mean "the statements and symbols in these files will be parsed multiple times causing warnings and errors", then no, the include guards will prevent that.
If by 'include' you mean "some part of compiler will read some part of these files", then yes, they'll be included multiple times. The preprocessor will read the second inclusion of the file and replace it with a blank line because of the include guards, which incurs a tiny overhead (the file is already in memory). Modern compilers (GCC, not sure about others) will probably be optimized to avoid this, however, and note that the file has include guards on the first pass and simply discard future inclusions, removing the overhead - Don't worry about speed here, clarity and modularity are more important. Compilation is a time-consuming process, for sure, but #include is the least of your worries.
To better understand include guards, consider the following code sample:
#ifndef INCLUDE_GUARD
#define INCLUDE_GUARD
// Define to 1 in first block
#define GUARDED 1
#endif
#ifndef INCLUDE_GUARD
#define INCLUDE_GUARD
// Redefine to 2 in second block
#define GUARDED 2
#endif
After (the first pass of) preprocessing, what will GUARDED be defined to? The preprocessor statement #ifndef or its equivalent, #if !defined() will return false if their argument is indeed defined. Therefore, we can conclude that the second #ifndef will return false, so only the first definition of GUARDED will remain after the first pass of the preprocessor. Any instance of GUARDED remaining in the program will be replaced by 1 on the next pass.
In your example, you've got something slightly (but not much) more complicated. Expanding all the #include statements in ExampleClient.c will result in the following source: (Note: I indented it, but that's not normal style for headers and the preprocessor won't do it. I just wanted to make it more readable)
/* ExampleClient.c */
//#include <stdlib.h>
#ifndef STDLIB_H
#define STDLIB_H
int abs (int number); //etc.
#endif
//#include <stdio.h>
#ifndef STDLIB_H
#define STDLIB_H
#define NULL 0 //etc.
#endif
//#include "mpi.h"
#ifndef MPI_H
#define MPI_H
void MPI_Func(void);
#endif
//#include "foo.h"
#ifndef FOO_H
#define FOO_H
//#include <stdlib.h>
#ifndef STDLIB_H
#define STDLIB_H
int abs (int number); //etc.
#endif
//#include "mpi.h"
#ifndef MPI_H
#define MPI_H
void MPI_Func(void);
#endif
void foo(void);
#endif
//#include "bar.h"
#ifndef BAR_H
#define BAR_H
//#include <stdlib.h>
#ifndef STDLIB_H
#define STDLIB_H
int abs (int number); //etc.
#endif
//#include "mpi.h"
#ifndef MPI_H
#define MPI_H
void MPI_Func(void);
#endif
void bar(void);
#endif
void main(int argc, char *argv[]) {
foo();
MPI_Func();
bar();
exit(0); // Added missing semicolon
}
Go through that code and note when various definitions are performed. The result is:
#define STDLIB_H
int abs (int number); //etc.
#define STDLIB_H
#define NULL 0 //etc.
#define MPI_H
void MPI_Func(void);
#define FOO_H
void foo(void);
#define BAR_H
void bar(void);
With respect to your request for other criticism/pointers, why are you #including stdlib.h and mpi.h in all your headers? I understand that this is a stripped down example, but in general, header files should only include files necessary for the declaration of their contents. If you use a function from stdlib or call MPI_func() in foo.c or bar.c, but the function declarations are simply void foo(void), you shouldn't include these files in the header function. For example, consider the following module:
foo.h:
#ifndef FOO_H
#define FOO_H
void foo(void);
#endif
foo.c:
#include <stdlib.h> // Defines type size_t
#include "mpi.h" // Declares function MPI_func()
#include "foo.h" // Include self so type definitions and function declarations
// in foo.h are available to all functions in foo.c
void foo(void);
size_t length;
char msg[] = "Message";
MPI_func(msg, length);
}
In this example, the implementation of foo() requires stuff from stdlib and mpi, but the definition does not. If foo() returned or required a size_t value (typedef'ed in stdlib), you'd need to #include stdlib in the .h file.
Mostly no, with a bit 'yes'. Your header files will be 'read' more than once but at second and later time the preprocessor will cut off all the contents. This implies that it won't waste your compiler's time and also #includes inside your #ifdef blocks will be done only once (per header file).
It's a good practice. Myself, I also add the following line before #ifdefs:
#pragma once
When supported by the particular compiler, it guarantees that the file will actually be read only once. I think it's a little bit more optimal that way.
So, to sum up:
header guards like you are using prevent compiler from interpreting the header contents more than once but possibly can cause the preprocessor to parse it more than once (which is not a big problem),
#pragma once causes the particular header file to be read only once.
When using both, #pragma once should be in effect if supported by compiler; if not, header guards will apply.
1) GOOD: you have an "include guard". "stdlib.h", "mpi.h" and "void foo()" are only seen by the compiler the first time you #include "foo.h"
/* foo.h */
#ifndef FOO_H
#define FOO_H
#include <stdlib.h>
#include "mpi.h"
void foo();
#endif
2) BAD: This will #include the entire contents of "foo.h" every time you use it:
/* foo.h */
#include <stdlib.h>
#include "mpi.h"
void foo();
3) By #include", I mean "once per compilation unit" (i.e. the same .c source file).
This mainly "protects" against a header (foo.h) calling another header ("bar.h) which might recursively call the first header.
Every different compilation unit that #includes foo.h will always get "stdlib.h", "mpi.h" and "void foo()". The point is that they'll be seen only once - not multiple times in the same compilation unit.
4) This is all "compile-time". It has nothing to do with libraries (which are "link time").
Yes, mpi.h will be included multiple times (as will stdlib.h); if mpi.h has include guards similar to foo.h and bar.h, then it won't be an issue.