In my current project. A lot of my .cpp and .h files have plenty of includes in them such as 6 or 7 of headers declared in the following manner.
#ifndef A_Header
#include "a.h"
#endif
#ifndef B_Header
#include "b.h"
#endif
I wanted to know would it make sense if I wrapped all of these headers (used in the project) in a single header and then declare that header in each source file as such
#ifndef Wrapper_Header
#include "wrapper.h" /*This would contain a collection of all headers*/
#endif
Any suggestions and drawbacks of this plan that I am not anticipating?
That's totally bizarre.
Every header should contain a header guard:
#ifndef THIS_HEADER
#define THIS_HEADER
/* contents of the header */
#endif
This goes inside the header, not in the including .cpp file. The compiler detects the header guard and avoids re-reading all the text when it's included again. This can save seconds of compilation time.
If your headers have that, then the guards in the .cpp file are extraneous and you should remove them. 6 or 7 headers isn't a lot, but that silly boilerplate does sure add up.
Never wrap your headers, always be explicit, make it clear what is included, and do not include what you do not need.
Potatoswatter is correct
But I like to add use "forward declaration".
I am sure you can google it.
Related
I've heard that you should prefer writing internal include guards instead of external include guards. I have searched around the internet but haven't found an answer to it.
This is a snippet of the book C++ Coding Standards by Herb & Andrei that shows an "external include guard":
Avoid using the obsolete external include guards advocated in older
books:
#ifndef FOO_HJNCLUDED_ //NOT recommended
#include "foo.h"
#define FOO_HJNCLUDED_
#endif
Now, this leads to the question below:
Q:
What is an internal include guard and what is an external include guard? What's the difference between the two, and why is internal include guards preferred? I would like that the answer also provide an example.
Edit: I ended up answering my own question.
Here's something I've seen that probably explains the comment.
Here, foo.h is defining an "internal include guard" (shortened to simply "include guard" by most people since it's the traditional way of doing it).
// foo.h
#ifndef _FOO_H__
#define _FOO_H__
// ...
#endif // _FOO_H__
In contrast, bar.h is using foo.h's include guard outside of foo.h. We can nickname this as an "external include guard".
// bar.h
#ifndef _BAR_H__
#define _BAR_H__
#ifndef _FOO_H__
#include "foo.h"
#endif
// ...
#endif // _BAR_H__
One (very large) project I worked on claimed that this increased compiling speed, but the claim is dubious as this seems to me like a trivial compiler optimization and I haven't seen any metrics to prove the claim. However, we did notice it was annoying to read when including multiple header files.
After a good digging around, I can now answer my own question.
Internal Include Guard:
The common idiom putting "include guards" around the content of header files being included:
header.h
#ifndef HEADER_H
#define HEADER_H
// Contents of include file
#endif
Therefore, the content of the header will be processed once even though the header is #includeed multiple times. This is known as an "internal include guard" because the guard is entirely internal to the header file.
External Include Guard:
However, there could be an issue with the above method if the compiler takes a simple approach, opening the file multiple times to check for "internal include guards" which could cause increased compile time in large projects.
header2.h
#ifndef HEADER_H
#include "header.h"
#endif
// Rest of header file goes here
The line: #ifndef HEADER_H is still defined and checked internally in header.h. But by checking it externally the compiler might avoid having to open the file at all.
It is only suggested to check externally when a header file is included from other header files. The check is not necessary when included from a source file.
Conclusion:
Internal guard guarantees correctness
External guard may improve speed of compilation on some compilers
The cost involved is that of putting the check everywhere a header file is #included in another header file, and spelling the name of the guard symbol correctly. Therefore not preferred.
how to check if one header include another header in c++?
for example, When I want to know if the include , but the include two many headers and header include other headers.So I have to check the source code one by one, So is there any quick method to find if one include another?
You should use an include guard. This will ensure the compiler does not include the header contents more than once.
An example header file, MyClass.h, using a standard include guard:
// MyClass.h
#ifndef MYCLASS_H
#define MYCLASS_H
// Your header contents goes here
#endif
This will ensure that the compiler only includes the header contents once.
Alternatively, you can use #pragma once.
An example header file, MyClass.h, using non-standard #pragma once:
// MyClass.h
#pragma once
// Your header contents goes here
Note that #pragma once is not standard, so it will make your code less portable. However, it does use less code, and can avoid name clashes.
If myheader.h has what we call an include guard, then it will usually #define a macro with a name like MYHEADER_H. So first check whether your header file has this kind of thing.
If it does, you can check at any point whether it has been included (up to that point), using the #ifdef and #ifndef directives.
in some cases, the header guard mentioned in other answers will not suffice (e.g. your file is used on multiple systems or is built against separate versions or libraries and the hguard is inconsistent). In those cases, you can:
look for another identifier which is #defined in that header
or simply replace your inclusion of that header with your own little wrapper header which has a #define which does not vary by platform/architecture, then replace your #includes with the wrapper header. To illustrate:
#ifndef MON_HGUARD_CXX_CSTDIO
#define MON_HGUARD_CXX_CSTDIO
// now replace the following #include with inclusion of this header
#include <cstdio>
#endif // MON_HGUARD_CXX_CSTDIO
When coding in either C or C++, where should I have the #include's?
callback.h:
#ifndef _CALLBACK_H_
#define _CALLBACK_H_
#include <sndfile.h>
#include "main.h"
void on_button_apply_clicked(GtkButton* button, struct user_data_s* data);
void on_button_cancel_clicked(GtkButton* button, struct user_data_s* data);
#endif
callback.c:
#include <stdlib.h>
#include <math.h>
#include "config.h"
#include "callback.h"
#include "play.h"
void on_button_apply_clicked(GtkButton* button, struct user_data_s* data) {
gint page;
page = gtk_notebook_get_current_page(GTK_NOTEBOOK(data->notebook));
...
Should all includes be in either the .h or .c / .cpp, or both like I have done here?
Put as much as you can in the .c and as little as possible in the .h. The includes in the .c are only included when that one file is compiled, but the includes for the .h have to be included by every file that uses it.
The only time you should include a header within another .h file is if you need to access a type definition in that header; for example:
#ifndef MY_HEADER_H
#define MY_HEADER_H
#include <stdio.h>
void doStuffWith(FILE *f); // need the definition of FILE from stdio.h
#endif
If header A depends on header B such as the example above, then header A should include header B directly. Do NOT try to order your includes in the .c file to satisfy dependencies (that is, including header B before header A); that is a big ol' pile of heartburn waiting to happen. I mean it. I've been in that movie several times, and it always ended with Tokyo in flames.
Yes, this can result in files being included multiple times, but if they have proper include guards set up to protect against multiple declaration/definition errors, then a few extra seconds of build time isn't worth worrying about. Trying to manage dependencies manually is a pain in the ass.
Of course, you shouldn't be including files where you don't need to.
Put as many includes in your cpp as possible and only the ones that are needed by the hpp file in the hpp. I believe this will help to speed up compilation, as hpp files will be cross-referenced less.
Also consider using forward declarations in your hpp file to further reduce the include dependency chain.
If I #include <callback.h>, I don't want to have to #include lots of other header files to get my code to compile. In callback.h you should include everything needed to compile against it. But nothing more.
Consider whether using forward declarations in your header file (such as class GtkButton;) will suffice, allowing you to reduce the number of #include directives in the header (and, in turn, my compilation time and complexity).
I propose to simply include an All.h in the project that includes all the headers needed, and every other .h file calls All.h and every .c/.cpp file only includes its own header.
I am making a small C++ framework, which contains many .h and .cpp.
I have created a general include which include all my .h file such as:
framework.h
#include "A.h"
#include "B.h"
#include "C.h"
each .h header are protected with include guard such as
#ifndef A_HEADER
#define A_HEADER
...
#endif
The issues is, I would like to be able to include "framework.h" inside all the sub .h such as, but it cause lots of compiler error:
#ifndef A_HEADER
#define A_HEADER
#include "framework.h"
...
#endif
If instead I use the real header file for each sub header, and the framework.h for what ever use my framework it works fine..
I would just like to include the main header inside all my sub .h so I dont need to include all the dependency everytime.
Thanks :)
Basically what your doing is #include "A.h" in framework.h and #include "framework.h" in A.h. This causes cyclic dependency of the header files and you will get errors such as undefined class A. To solve this, use forward declarations in header file and #include only in corresponding cpp file. If that is not possible then I don't see any other option other than including individual header files.
Just protect the main header with include guards too:
#ifndef FRAMEWORK_H
# define FRAMEWORK_H
# include <A.h>
# include <B.h>
# include <C.h>
#endif
That will prevent recursive inclusion.
You should not including the main header file inside the sub-header files. It should be used to make user's life easier, not yours.
Instead do following:
1) Make forward definitions of all you need in the related sub-header files.
2) Include only needed sub-header files inside CPP files.
3) When using your framework inside an application code (for example), then you could include the main framework header file.
i would recommend using #pragma once, and placing that at the top of all of your header files (framework.h, A.h, B.h, and C.h).
Although, if you'd rather, I think you could fix your problem by simply putting an include guard in framework.h as well.
I guess you have a dependency between - say B and C such that B depends on C, but in framework.h C is included after B.
Circular includes are generally a bad idea in C++. While having header guards will prevent the preprocessor from going into infinite loop (or throwing an error because of this), you will get unexpected compiler errors, because at some point a header file will not be included when if you think it is.
You should include A.h, B.h and C.h from framework.h, and in A.h, do not include framework.h, just forward declare the classes you use from it. Or do it the other way around: include framework.h from A.h, B.h and C.h, and forward declare classes in framework.h. And, of course, put every code that would require any more detailed declarations than for example class A to the .cpp files.
how does header including in c++ work? I have the classes already implemented in .h file and when there is #include in two files, there's this error:
files.h:14:7: error: redefinition of ‘class abstract_file’
files.h:14:20: error: previous definition of ‘class abstract_file’`
multiple times for each class and enum.
Can anyone explain this?
Using include in C++ simply takes the file included and splats the contents into where it is included. To do this without worrying about multiple includes of the same file, you want to use header guards. Use this basic format for all header files:
#ifndef FILENAME_H
#define FILENAME_H
class foo (or whatever else is in the file!) {
...
};
#endif
You can only include a definition one time but headers can be included multiple times. To fix that, add:
#pragma once
to the top of each header file.
While #pragma once is relatively common, if you are using an older compiler it may not be supported. In that case, you need to fall back on manual include guards:
#ifndef MY_HEADER_H
#define MY_HEADER_H
...
#endif
(note that you need to replace MY_HEADER_H with a unique string for each header file)
header files usually define a unique symbol so that they are only included once.
e.g.
#ifndef _myheader_h
#define _myheader_h
// rest of header goes here
#endif
Some compilers support
#pragma once
See Pragma Once on wikipedia.
While many people have solved your error for you, it seems that nobody has answered your initial question:
how does header including in c++ work?
When the preprocessor finds an #include directive it replaces it by the entire content of the specified file.
You can read more on preprocessor directives at cplusplus.com.
Update: To illustrate this, you could try the following if you have gcc handy:
echo '#include <iostream>' > test.cxx
gcc -E test.cxx
You'll see the contrents of iostream whizz past your eyes as the preprocessed source code is sent to standard output.
What you can do is to guard your header from multiple inclusions:
#ifndef MY_HEADER__
#define MY_HEADER__
/* your stuff goes here! */
#endif
You can also use:
#pragma once
but it is not standard although it is supported by many compilers.
Use include guards in header files:
#ifndef FILES_H
#define FILES_H
struct foo {
int member;
};
#endif // FILES_H
This makes sure that your header will only get included once.
Another method is to use #pragma once in your header files, but it's not standard C. It's supported by Visual C, GCC and Clang though, so most likely it's ok to use.