At LearnCpp.com | 1.10 — A first look at the preprocessor. Under Header guards, there are those code snippets:
add.h:
#include "mymath.h"
int add(int x, int y);
subtract.h:
#include "mymath.h"
int subtract(int x, int y);
main.cpp:
#include "add.h"
#include "subtract.h"
In implementing the header guard, it is mentioned as follows:
#ifndef ADD_H
#define ADD_H
// your declarations here
#endif
What could the declaration be here? And, should int main() come after #endif?
Is adding _H a convention or a must do thing?
Thanks.
The FILENAME_H is a convention. If you really wanted, you could use #ifndef FLUFFY_KITTENS as a header guard (provided it was not defined anywhere else), but that would be a tricky bug if you defined it somewhere else, say as the number of kittens for something or other.
In the header file add.h the declarations are literally between #ifndef and #endif.
#ifndef ADD_H
#define ADD_H
#include "mymath.h"
int add(int x, int y);
#endif
Finally, int main() shouldn't be in a header file. It should always be in a .cpp file.
To clear it up:
#ifndef ADD_H basically means "if ADD_H has not been #defined in the file or in an included file, then compile the code between #ifndef and #endif directives". So if you try to #include "add.h" more than once in a .cpp file, the compiler will see what the ADD_H was already #defined and will ignore the code between #ifndef and #endif. Header guards only prevent a header file from being included multiple times in the same .cpp file. Header guards don't prevent other .cpp files from including the header file. But all .cpp files can include the guarded header file only once.
The result of preprocessing one implementation (".cpp") file is a translation unit (TU).
Headers can include other headers, so a header may be indirectly included multiple times within the same TU. (Your mymath.h is an example of this.)
Definitions can only occur at most once per TU. (Some definitions must also not be in multiple TUs; this case is slightly different and not discussed here.)
The problem include guards solve is preventing multiple definition errors when a given header is included more than once within one TU.
Include guards work by "wrapping" the contents of the header in such a way that the second and subsequent includes are no-ops. The #ifndef/#define directives should be the first two lines of the file, and #endif should be the last.
Include guards are only used in headers. Do not define your main function in a header: put it in an implementation file.
If you have a header that will define a type and declare a function, but also needs a header itself:
#include "other_header.h"
struct Example {};
void f();
"Wrapping" it with include guards gives the complete contents of the file:
#ifndef UNIQUE_NAME_HERE
#define UNIQUE_NAME_HERE
#include "other_header.h"
struct Example {};
void f();
#endif
The name used for the include guard must be unique, otherwise conflicting names will give confusing results. These names are only simple macros, and there is nothing in the language which enforces a certain style. However, project conventions usually impose requirements. There are several different include guard naming styles you can find here on SO and elsewhere; this answer gives good criteria and a good overview.
All the header guards do is to only allow your headers to be included once. (If they're included multiple times, they're ignored.)
The name you use doesn't matter, but it's conventional to use the file name in caps, including the extension like you demonstrated.
Your main should really be in a .cpp file, but if you're putting it in a header, put it inside the guards so it isn't declared multiple times.
No, the int main() goes in a .cpp. The declarations are the other stuff you were gonna put in the header. _H is a convention, you can see various header guard conventions around.
I declare a declaration in header file and definitions or int main() comes in source.cpp file.
_H is there to merely indicate that someone is going to include header files using include guards.
If you're on MSVC++ you can also use #pragma once
Related
Lets say I am using header guards,
#ifndef MAIN_H
#define MAIN_H
#include "foo.h"
#include "some_header_file.h"
... // Some Code
#endif
Inside foo.h file also with Header guards.
#ifndef FOO_H
#define FOO_H
#include "some_header_file.h"
... // Some Code
#endif
As you can see main file have 2 headers one of them is dublicate. I have three questions:
Does Header guards prevent duplicate header files?
Does the compiler optimize it and removes it?
Is this a bad practice and the extra header file should be deleted from main file?
Does Header guards prevent duplicate header files?
Yes. The first encountered inclusion will bring the content of the header to the translation unit, and the header guard causes successive inclusions to be empty which prevents the content of the header from being duplicated. This is exactly the reason why header guards are used.
or is this a bad practice and the extra header file should be deleted from main file?
No, the duplicate inclusion is not a bad practice. If the "main" header depends on any declaration from "some_header_file.h", then "main" absolutely should include "some_header_file.h" directly, whether another header - even one included by "main" - also includes it or not.
Relying on a transitive inclusion would generally be a bad practice - i.e. in this case it may be bad to rely on the detail that "foo.h" includes "some_header_file.h" when including "foo.h" into "main". Such assumptions often can cause programs to break unexpectedly when they are modified. In this case, if "foo.h" was modified to no longer depend on "some_header_file.h", and that inclusion was removed, then that change would suddenly cause the assumption to fail, and "some_header_file.h" would no longer be included into "main" as a result of change that didn't involve "main" at all. That would be bad.
The main problem with repited includes is when two different files include each other. For example, if a.h include b.h, and b.h includes a.h, if you don't add header guards, preprocessor ends up in a cycle, because every time it reads a.h includes b.h, and b.h includes a.h, and this never ends.
In your case you could have some problem if you define a variable in your some_header_file.h", because it would be read twice and the variables would be declared twice also, which would result in a compiler error.
You need to add them in "some_header_file.h", that way next time preprocessor reads this file it would ignore it by the ifndef clause. And notice the importance for cyclic include dependencies.
In "some_header_file.h" add:
#ifndef SOME_HEADER_FILE_H
#define SOME_HEADER_FILE_H
...code
#endif /* SOME_HEADER_FILE_H */
Last comment isn't necessary, but it helps case you need to debug/review preprocessors output.
Example:
#ifndef HEADER_h
#define HEADER_h
#endif
Instead of HEADER_h, can I do the following?
#ifndef HEADER
or
#ifndef LIBRARY
or
#ifndef SOMETHING
or
#ifndef ANOTHERTHING
etc.
Header guards are just a convention, a "trick", making use of preprocessor conditions. In using a header guard you are creating a macro with a name, and checking whether that macro was already defined.
There is nothing magical about this macro that binds it to the filename of a header, and as such you can call it whatever you want (within reason).
That doesn't mean that you should write #ifndef URGLEBURGLE, though. You want the name to be useful and unique, otherwise there's not much point.
Typically something like #ifndef [PROJECTNAME]_[FILENAME]_INCLUDED is a good idea.
Yes, you can name the include guard symbol whatever you want, but bear in mind that they are supposed to be unique across headers. You definitely don't want a header
// first.h
#ifndef NON_UNIQUE_H
#define NON_UNIQUE_H
void foo();
#endif
and another one
// second.h
#ifndef NON_UNIQUE_H
#define NON_UNIQUE_H
void bar();
#endif
When you include both in one translation unit, one will "win" and its declarations will be visible, e.g.
// main.cpp
#include "first.h" // now, NON_UNIQUE_H is defined
#include "second.h" // NON_UNIQUE_H already there, doesn't do anything
int main(int, char**)
{
bar(); // error, won't compile, bar() isn't declared
}
Besides the necessity to circumvent such scenarios, it's best to stick to some convention throughout your project. One classical way of doing it is to convert the header file base name to upper case and append _H. If you have header files with the same base name in different directories, you can include the directory name, e.g. SUBDIR_FOO_H and OTHERSUBDIR_FOO_H. But this is up to you.
You can use a construction like
#if !defined(HEADER) || !defined(LIBRARY)
At your question, you are using
#ifndef HEADER_h
#define HEADER_h
#endif
It's the same as "#pragma once"
And yes, you can use different names of defines. In your case, LIBRARY, SOMETHING, HEADER_h - defines, that you can set in code(#define MY_VAR_NAME) or via compiler options(flag -DMY_VAR_NAME).
Your example is a so-called header guard that allows us to ensure the contents of the header are included only once. However, that is not the only use of #ifndef.You can use #ifndef for conditional compilation as in
#ifndef NO_DEBUG
do_some_debug_stuff();
#endif
So it is not only for header guards, but in general you have to carefully choose the name of the symbols you are introducing to prevent they are clashing with symbols defined elsewhere. It is just that header guards are so common that certain conventions exist (eg using FOLDER_FILENAME_H is usually sufficient to ensure uniqueness). And you need to be aware that certain names are reserved (eg starting with two underscores or underscore followed by capital letter).
What is "ICT_TOOLS_H__"? Is it a header that I'm defining here, or is it a boolean, or an int of 1 or 0? Does the name have to be the same as the header file, or can it be a custom name? Also, do I use #ifndef if the header is included in multiple .cpp files, or should I use it even if it's only #included once? When the compiler goes through the first time, does "ICT_TOOLS_H__" get defined and on every other pass through it doesn't recompile the header, preventing multiple compilations of the same header?
#ifndef ICT_TOOLS_H__ //my proff said to start the name with "ICT_", its the programming department
#define ICT_TOOLS_H__
//implementation goes here
#endif
no it is a macro used for inclusion guard conditional inclusion so at first always this macro is not defined so the condition succeeds and the content is added to the source/header (where included) and in the second time the condition will fail so the content won't be added again.
this is useful when having multiple source/header files where you can include a header twice or more.
//header.h
#ifndef MY_HEADER_H // the name can be anything
#define MY_HEADER_H
// code here (some declarations)
int value;
#endif
//source.cpp
#include "header.h"
#include "header.h"
int main()
{
value = 0; // for example
return 0;
}
if you remove the inclusion guard then the content of header.h will be added twice so as a result two variables value are there and that is a compile-time-error (redefinition).
They are basically macros and are used for conditional compilation.
This is how they work the compile first checks if there is a defined macro called in your case ICT_TOOLS_H__ if it is not defined then the entire code between #ifndef and #endif will compile and as the next line indicates it will define that macro and will be a guard not to compile it again.
If a code compiles more than one time the c++ one definition rule is violated. See here https://en.m.wikipedia.org/wiki/One_Definition_Rule .
At LearnCpp.com | 1.10 — A first look at the preprocessor. Under Header guards, there are those code snippets:
add.h:
#include "mymath.h"
int add(int x, int y);
subtract.h:
#include "mymath.h"
int subtract(int x, int y);
main.cpp:
#include "add.h"
#include "subtract.h"
In implementing the header guard, it is mentioned as follows:
#ifndef ADD_H
#define ADD_H
// your declarations here
#endif
What could the declaration be here? And, should int main() come after #endif?
Is adding _H a convention or a must do thing?
Thanks.
The FILENAME_H is a convention. If you really wanted, you could use #ifndef FLUFFY_KITTENS as a header guard (provided it was not defined anywhere else), but that would be a tricky bug if you defined it somewhere else, say as the number of kittens for something or other.
In the header file add.h the declarations are literally between #ifndef and #endif.
#ifndef ADD_H
#define ADD_H
#include "mymath.h"
int add(int x, int y);
#endif
Finally, int main() shouldn't be in a header file. It should always be in a .cpp file.
To clear it up:
#ifndef ADD_H basically means "if ADD_H has not been #defined in the file or in an included file, then compile the code between #ifndef and #endif directives". So if you try to #include "add.h" more than once in a .cpp file, the compiler will see what the ADD_H was already #defined and will ignore the code between #ifndef and #endif. Header guards only prevent a header file from being included multiple times in the same .cpp file. Header guards don't prevent other .cpp files from including the header file. But all .cpp files can include the guarded header file only once.
The result of preprocessing one implementation (".cpp") file is a translation unit (TU).
Headers can include other headers, so a header may be indirectly included multiple times within the same TU. (Your mymath.h is an example of this.)
Definitions can only occur at most once per TU. (Some definitions must also not be in multiple TUs; this case is slightly different and not discussed here.)
The problem include guards solve is preventing multiple definition errors when a given header is included more than once within one TU.
Include guards work by "wrapping" the contents of the header in such a way that the second and subsequent includes are no-ops. The #ifndef/#define directives should be the first two lines of the file, and #endif should be the last.
Include guards are only used in headers. Do not define your main function in a header: put it in an implementation file.
If you have a header that will define a type and declare a function, but also needs a header itself:
#include "other_header.h"
struct Example {};
void f();
"Wrapping" it with include guards gives the complete contents of the file:
#ifndef UNIQUE_NAME_HERE
#define UNIQUE_NAME_HERE
#include "other_header.h"
struct Example {};
void f();
#endif
The name used for the include guard must be unique, otherwise conflicting names will give confusing results. These names are only simple macros, and there is nothing in the language which enforces a certain style. However, project conventions usually impose requirements. There are several different include guard naming styles you can find here on SO and elsewhere; this answer gives good criteria and a good overview.
All the header guards do is to only allow your headers to be included once. (If they're included multiple times, they're ignored.)
The name you use doesn't matter, but it's conventional to use the file name in caps, including the extension like you demonstrated.
Your main should really be in a .cpp file, but if you're putting it in a header, put it inside the guards so it isn't declared multiple times.
No, the int main() goes in a .cpp. The declarations are the other stuff you were gonna put in the header. _H is a convention, you can see various header guard conventions around.
I declare a declaration in header file and definitions or int main() comes in source.cpp file.
_H is there to merely indicate that someone is going to include header files using include guards.
If you're on MSVC++ you can also use #pragma once
If I do the following:
dConst.hpp
const int POWER_LEVEL = 9001;
genPower.hpp
#include "dConst.hpp"
#ifndef GENPOWER_HPP
#define GENPOWER_HPP
const int GENERATOR[1] = { POWER_LEVEL };
#endif
I end up getting linker errors for any code that utilizes the generator array constant.
However, if I switch the #include "dConst.hpp" with the code block:
#ifndef GENPOWER_HPP
#define GENPOWER_HPP
It works...
Am I misusing the power of the #ifndef?
You are under-using the power of #ifndef.
Your dConst.hpp file needs include guards. Otherwise, it will cause problems (the exact problems you saw) if it is included from more than one file within a translation unit.
EDIT: I would also place your include guards in genPower.hpp at the top of the file, before your include statements.
Yes, definitely.
The point of include guards is to make sure your code doesn't get included twice - if you have some code in your header files that's not inside the include guard, if you include that header twice, you're defining everything outside the guards twice.
For a bit of a better idea of what's going on, your generated code looks something like this:
The #include basically just inserts the contents of the included file directly into the other file in place, meaning that your genPower.hpp looks like this (without the include guards in place properly, like you have originally in your question):
const int POWER_LEVEL = 9001;
#ifndef GENPOWER_HPP
#define GENPOWER_HPP
const int GENERATOR[1] = { POWER_LEVEL };
#endif
Therefore, every time you include that file, before the #ifndef gets reached, POWER_LEVEL gets defined. If you switch the POWER_LEVEL lines with the #ifndef/#define, every time you include this file, it will first CHECK if it's already been included (with the #ifndef - if it's already been included, the #define should have done its work) and ONLY THEN (once it's figured out this is the first time) will it define POWER_LEVEL.
Also, you almost definitely want include guards on your dConst.hpp as well - ALL headers should have include guards, and they should guard EVERYTHING in the header file. That's your mistake with #ifndef.