Hello!
I want to include the same headerfile in more than one sourcefile and of course have to take care that each Headerfile is included just once.
I really have no clue, why this works for the Headers provided by Keil but not with my own ones:
#ifndef _MYHEADER_H_ #define _MYHEADER_H_
//Headerfile content . ..
#endif
Obviously the preprocessor includes the Headerfile more than once and so i get errors.
When i add a statement within my Header like:
#warning "included more than once"
the warning message appears twice. (so the header is really included twice).
Can anyone tell me the problem please?!
Kind regards
Obviously the preprocessor includes the Headerfile more than once
More than once in a single file? I assume you mean in different .c files. Could it be that you see the multiple #warning statements from 2 different .c file compilations in a build environment? Each individual .c file does need to include the .h file when it is compiled.
Are you using any #undef's?
-- Joost
Thanks for the reply!
Yes i mean more than once in different .c Files.
There are two .c Files, which both include the same Headerfile.
Within this Headerfile i have used the #ifdef .... #endif commands to avoid that the preprocessor includes the Headerfile a second time when it was already included by the first .c File.
I donÂ't use #undefÂ's anywhere in code!
Thanks for your support ;-)
"There are two .c Files, which both include the same Headerfile."
So long as each file includes the header only once, that is exactly what you want!
The purpose of the so-called "include guards" is to prevent the header from being included more than once in the same file!
Essentially, the compiler only ever sees one source file at a time - that's why you need to include the necessary headers in each file, and why it isn't a problem when two different 'C' files include the same header file.
Having said that, if your header files are faulty, they can give you problems - especially if they contain definitions of data and/or code items, rather than just declarations...
There are two .c files, which both include the same headerfile.
Within this headerfile i have used the #ifdef .... #endif commands to avoid that the preprocessor includes the Headerfile a second time when it was already included by the first .c file.
This is not a problem. Like I said, each .c file needs to include the header file to see all the externals etc.
A problem can occur when the compiler tries to include a header file twice when compiling a single .c file. Symbols will be declared twice which is an error.
Example 1: header.h file1.c -> include header.h -> OK file2.c -> include header.h -> OK No #ifdef is needed. If you add an #ifdef in header.h and include the #warning, you will still see the warning twice because both file need to be compiled.
Example 2: global.h header1.h -> includes global.h header2.h -> includes global.h as well file1.c -> include header1.h -> OK include header2.h -> ERROR, global.h already included file2.c -> include header1.h -> OK include header2.h -> ERROR, global.h already included
Here, an #ifdef is needed for global.h
In each example two compiles are needed, one for each .c file.
Because it's difficult to track which header file includes which header file, it's a good idea to put the #ifdef's in all header files, just to be sure.
What error's are you getting?
-- J
The
#ifndef xx #define xx ... #endif
method is to make sure that a header file isn't included more than once from the same c file.
You can not - and normally don't want to - stop multiple c files from including the same header file.
A header file is included because: 1) You have specifically added a line #include "xx" or #include <xx> in the source file. Don't do that unless you want the file to be included :) 2) You are including one header file, that it it's turn (one or more steps away) includes another header file. But a header file should only contain a recursive #include if it really needs that other file for some declarations. Hence, you need to include it.
What does this mean?
If the header file must be seen by multiple source files, you can't use it to allocate global variables, since the linker would then complain about multiple sets of global variables with the same name. This can be solved with the following:
//globals.h #ifndef _GLOBALS_H #define _GLOBALS_H #if defined MAIN #define EXTERN #else #define EXTERN extern #endif ... EXTERN int my_global_variable; #endif // _GLOBALS_H
// main.c #define MAIN #include "globals.h" ...
// misc.c #include "globals.h" ...
In this case, only the inclusion in main.c will result in an "allocation" of global variables, because the #define EXTERN will be empty. All other source files that includes "globals.h" will just see the type information for the global variables.
Example 2 should have read:
Sorry about that...
Ok!
Thank you all for the help!
I am a beginner and NOW i think i understand the purpose of the #ifndef .. :-)
So in my context i generally would not need it.
However, i have compiled a Library in Keil and for this Library a Header File exists, in which all Prototypes of the functions defined in the Library are listed.
If i now include the Header File of this Lib in more than one .c File, get errors which tells me "Multiple public definitions".
So it seems that the symbols in this Library-Header are "included" more than once?!
Kind regards!
Sorry, the post of Per Westermark should explain this problem. ;-)
Have overseen it...
Thanks!!
It's a good idea to use it in all your header files. Just to be safe.
Maybe you could post a bit of code so all of us can have a look. Make sure you use the ANSI C keyword extern in the header file to tell the compiler that it's a declaration of a variable or function and not a (obviously multiple) definition
Coming from somebody who only just understood what they were ever needed for in the first place, that's a dangerously confident generalization. For the time being, you should follow time-proven coding rules, and one of those is to treat multiple-inclusion guards like your safety belt: don't think about it, just fasten it.
That's got nothing to do with multiple-inclusion guards. It's telling you that you have put stuff in your library's public header that doesn't belong in header files: definitions of variables. In short, some variable declarations in your header are missing the "extern" specifier.
Try a search for those two keywords together - it's been explained before.
See also: c-faq.com/.../decldef.html