I'm creating an header-only C++11/14 library and I'm not sure on how I should handle #include directives between library files.
Should I try to group as many #include directives as possible in the user-oriented module header file or should internal files include files they require (sometimes repeating the same includes)?
Approach A:
In this approach, the module header file includes all required dependencies and then includes the implementations. The implementations' header files do not include anything by themselves.
// Library/Module/Module.hpp
// This file is intended to be included by the user in his projects.
#ifndef MODULE
#define MODULE
#include <vector>
#include "Library/Module/Impl/SharedDependency.hpp"
#include "Library/Module/Impl/Class1.hpp"
#include "Library/Module/Impl/Class2.hpp"
#endif MODULE
-
// Library/Module/Impl/SharedDependency.hpp
#ifndef SHARED_DEPENDENCY
#define SHARED_DEPENDENCY
inline void sharedFunc() { }
#endif
-
// Library/Module/Impl/Class1.hpp
#ifndef CLASS1
#define CLASS1
// No need to include "SharedDependency.hpp", as it will be included by
// the module header file. Same applies for <vector>.
struct Class1
{
std::vector<int> v;
Class1() { sharedFunc(); }
};
#endif
-
// Library/Module/Impl/Class2.hpp
#ifndef CLASS2
#define CLASS2
// No need to include "SharedDependency.hpp", as it will be included by
// the module header file. Same applies for <vector>.
struct Class2
{
std::vector<int> v;
Class2() { sharedFunc(); }
};
#endif
Approach B:
In this approach, the module header file includes only the implementation headers. If the implementation headers require additional includes, they include the files themselves (recursively), sometimes repeating the same include.
// Library/Module/Module.hpp
// This file is intended to be included by the user in his projects.
#ifndef MODULE
#define MODULE
#include "Library/Module/Impl/Class1.hpp"
#include "Library/Module/Impl/Class2.hpp"
#endif MODULE
-
// Library/Module/Impl/SharedDependency.hpp
#ifndef SHARED_DEPENDENCY
#define SHARED_DEPENDENCY
inline void sharedFunc() { }
#endif
-
// Library/Module/Impl/Class1.hpp
#ifndef CLASS1
#define CLASS1
#include <vector>
#include "Library/Module/Impl/SharedDependency.hpp"
struct Class1
{
std::vector<int> v;
Class1() { sharedFunc(); }
};
#endif
-
// Library/Module/Impl/Class2.hpp
#ifndef CLASS2
#define CLASS2
#include <vector>
#include "Library/Module/Impl/SharedDependency.hpp"
struct Class2
{
std::vector<int> v;
Class2() { sharedFunc(); }
};
#endif
What is the best approach?
Intuitively, I think Approach A is the best, as it avoids repeating the same includes and makes clear what files need to be included before the other files. The biggest drawback is, though, that syntax highlighting stops working in my IDE (QT-Creator), in the implementation files with no include directives.
EDIT:
This question was voted to be closed for the reason "opinion based". I disagree, because in a large header-only project such as my library including files may take a lot of compile time. Therefore, approach A may be faster than approach B, or the opposite.
Approach B is actually the best approach, since including the same header multiple times does not produce any observable compilation time increase, but is advantageous for the following reasons:
Modern IDEs can use libclang or proprietary solutions to parse the #include directives and provide code-aware syntax highlighting and autocompletion features.
As mentioned by TemplateRex, it becomes much easier to verify a sane build process. CMake, for example, provides macros that automatically generate a test for every header.
As mentioned by Alf, it is good practice to have every file include all the headers it depends on - users of the library can then "cherry-pick" header files they require, instead of being unexpectedly force to manually include a parent header.
Related
In this example code, I have 3 files:
testHeader.h:
void hello() { }
file1.h:
#include "testHeader.h"
#include <iostream>
void sayHi() { std::cout << "hi" << std::endl; }
file2.h:
#include "file1.h"
void sayHello() { std::cout << "hello" << std::endl; }
If file1.h includes testHeader.h and file2.h includes file1.h, do testHeader.h and its functions become accessible in file2.h? What about <iostream> and its functions?
Unless protected by preprocessor guards in weird ways, yes, you get them all. #include is largely a preprocessor trick, roughly equivalent to dumping the text of the include into the source code, and it's transitive; if you #include <a.h>, you get the expanded form of a.h, including the preprocessor expanded form of all its includes, all their includes, etc., etc. ad infinitum, in a single pass.
Note that it's still a good idea to explicitly include all the things you rely on directly; sure, the other .h files might #include <vector> today, but that's no guarantee the next release will have them if they're not a necessary part of the API being exposed.
It's also worth noting that preprocessor include guards (and/or #pragma once) is used almost universally to mean a .h file's contents don't get included twice (by convention, not a guarantee; in the case of poorly written .h files, or weird ones designed for multiple inclusion with different preprocessor setups it won't be obeyed); there is little to no cost to re-including a header in the .cpp that it already got from a .h you included. On older compilers, without #pragma once and with no special handling for include guards, it might have to load the header a second time, see the guard, and dump nothing on the second include; many newer compilers are smart enough to avoid even that cost. Point is, don't try to optimize by avoiding redundant #includes; every file should have the complete set of #includes needed for the things used in that file, no more, no less.
If you work on older compilers, without #pragma once, then try to do as following.
--- file1.h ---
#ifndef FILE1_H
#define FILE1_H
#include "testHeader.h"
#include <iostream>
void sayHi();
#endif
--- file1.cpp ---
#include "file.h"
void sayHi() { std::cout << "hi" << std::endl; }
--- file2.h ---
#ifndef FILE2_H
#define FILE2_H
#include "file1.h"
#include <iostream>
void sayHello();
#endif
You shouldn't make a body of function in HEADER file. It might cause a compile error for multiple links for the same function. Please write function' prototype and body into Header and Source file seperately.
Wt recommends to use forward declarations to avoid circular dependencies.
// Settings.h
#include <Wt/Dbo/Dbo.h>
#include <string>
class User; // Forward declaration of User Wt::Dbo object
class Settings
{
public:
Wt::Dbo::ptr<User> user;
template<class Action>
void persist(Action& a)
{
Wt::Dbo::belongsTo(a, user);
}
};
// User.h
#include <Wt/Dbo/Dbo.h>
#include <string>
#include "Settings.h"
class User
{
public:
Wt::Dbo::weak_ptr<Settings> settings;
template<class Action>
void persist(Action& a)
{
Wt::Dbo::hasOne(a, settings);
}
};
However, when I use this Settings class in another cpp file, the program doesn't compile:
// test.cpp
#include "Settings.h"
error: C2079: 'dummy' uses undefined class 'User'
Possible solutions (which I do not like)
A solution is to include in User.h in every cpp file that includes Settings.h, i.e.:
// test.cpp
#include "User.h"
#include "Settings.h"
I do not prefer this solution, because I have to remember to include User.h every time I include Settings.h.
Another solution is to use the non-recommended DBO_EXTERN_TEMPLATES macro, i.e.
// Settings.h
...
class Settings
{
public:
....
};
DBO_EXTERN_TEMPLATES(Settings)
I do not prefer this solution as this macro is not recommend, nor documented. DBO_EXTERN_TEMPLATES doesn't work with all compilers.
Question
a. What is the best/preferred methodology to overcome circular dependencies between Wt::Dbo objects avoiding the mentioned undefined class error?
b. Why does solution 1. works?
I created a new (general - not Wt::Dbo specific) question (with an MCVE), to clarify the specific situation: When are member functions of a templated class instantiated?
References
DBO_EXTERN_TEMPLATES: https://www.mail-archive.com/witty-interest#lists.sourceforge.net/msg06963.html
Wt::Dbo and circular depencies: https://redmine.webtoolkit.eu/boards/2/topics/290?r=292
The given example is based on the Wt::Dbo tutorial: https://www.webtoolkit.eu/wt/doc/tutorial/dbo.html#_em_one_to_one_em_relations, but I want to place the different classes into different header files.
I'm not familiar with Wt::Dbo, but I don't believe the issue is specific with it. It is more a general C++ class design issue, which you need to work around/with; it is actually rather common in C++ projects.
For the "best/preferred method," that really is a matter of opinion. In your case, you can actually have both User.h and Settings.h include each other, if you still have the forward declarations.
For example, in Settings.h:
// include guard
class User;
#include "User.h"
class Settings { ... };
Then in User.h, you can do:
// include guard
class Settings;
#include "Settings.h"
class User { ... };
I know this seems odd, but it is a way to ensure you don't have to include both headers all the time. Alternatively, you just do that in one header, and ensure that is the one you always include.
In general, my preferred way is, in header files, only include what is absolute needed in the header, and forward declare the rest. In the source files, I then include the headers which are actually needed. The reason for this is because then, if I need to change one header file, I don't have to recompile all the source files which included that header; it improves the performance of the compilation process.
As for your question as to why solution 1 works, it's because of how you are including the files. In that specific example, you don't even need to include Settings.h in the source file, because User.h already does this. But let's look at how it looks once the pre-processor is done with it.
When you include User.h, it first includes Settings.h. An include basically copies the contents into the current file where the include occurred. So, effectively, your User.h would look something like this:
// User.h
#include <Wt/Dbo/Dbo.h> // contents from this would be here
#include <string> // contents from this would be here
// Settings.h
#include <Wt/Dbo/Dbo.h> // contents NOT included, due to previous include and include guards
#include <string> // same as above
class User; // Forward declaration of User Wt::Dbo object
class Settings
{
public:
Wt::Dbo::ptr<User> user;
template<class Action>
void persist(Action& a)
{
Wt::Dbo::belongsTo(a, user);
}
};
class User
{
public:
Wt::Dbo::weak_ptr<Settings> settings;
template<class Action>
void persist(Action& a)
{
Wt::Dbo::hasOne(a, settings);
}
};
What you can see now, is that when the Settings class is being defined, the User is already forward declared and can be used by the Settings class. When User is then defined, it has the full definition of Settings to work with. In your test.cpp file now, both Settings and User are fully defined, and hence can be used.
I hope this helps :)
Based on the answer of ChrisMM, another solution is to forward declare your class at the top of its header file:
Settings.h:
// include guard
class Settings;
#include "User.h"
class Settings { ... };
Users.h:
// include guard
class User;
#include "Settings.h"
class User { ... };
The advantage of this approach is that you only have to forward declare the class in its own header file and are allowed to just include the file in any other (header) file that need it.
So I am just wondering if you #include something in a for example header.h file:
For example this is called header.h:
#include <vector>
#include <iostream>
#include <somethingElse>
So if for example I make a file called something.cpp Do I need to put all those include statements again?
#include "header.h"
// If I include #header.h in this file. Do the #include carry over to this file. Or do they not
I am wondering because whenever I include <vector> something in my .h file the #include statements that I used previously in the .h file always turn grey which means they are not used. Is it because I used it in the .h file? Its not a problem or anything I am just curious.
You don't need to include those headers again because your compiler can find those headers. You can also try to read and understand the makefile (or CMakeList) which will help.
Try always to avoid "Multiple file inclusion" via using inclusion guard or #pragma once in order to prevent the multiple file inclusion.
To include file means that the content of the file will be added to the very place you wrote include.
Here's an example:
// header.h
const int vlaue = 10;
const int value2 = 0;
// main.cpp
#include "header.h"
#include "header.h"
Above the content of "header.h" is added twice to main.cpp.
Do you know what is the result? It's a compile-time error complaining of redefinition of value and value2.
In the above example I think green programmers don't get trapped by it but it is just an explanation, So what I talk about is when a huge program where many header files and many source files and some files include others then it'll be so difficult to track the right file inclusion.
The workaround that is to use inclusion guards or pragma once eg:
Let's modify our header.h to look like:
// header.h
#ifndef MY_HEADER_H
#define MY_HEADER_H
const int vlaue = 10;
const int value2 = 0;
#endif
Now in main.cpp:
#include "header.h"
#include "header.h"
#include "header.h"
The code above works fine and no duplicate of header content is added to main.cpp. Do you know why? It's the magic of Macro there. So at first time the pre-processor checks whether a macro has been already defined with the name MY_HEADER_H or not and for sure for the first time it is not defined so the content is added. The second and so on the condition fails because the macro is already defined thus the content of header.h will not be added to where it is called.
The draw back of inclusion guard is if you have a macro with same name as the inclusion guard thus it is already defined so the content will never be added (empty content). Thus you get a compile-time error:
value, `value2` undeclared identifiers.
The second solution is using pragma eg:
Let's modify our header.h file:
// header.h
#pragma once
const int vlaue = 10;
const int value2 = 0;
// main.cpp
#include "header.h"
#include "header.h"
The code above works correctly so no multiple inclusion of header.h That is because of the magic of pragma once: which is a non-standard but widely supported pre-processor directive designed to cause the current source file to be included only once in a single compilation. Thus, #pragma once serves the same purpose as include guards, but with several advantages, including: less code, avoidance of name clashes, and sometimes improvement in compilation speed.
Finally you should include header wherever their content is used eg:
// Shape.h
class Shape{
// some code here
};
// Cube.h
#include "Shape.h"
class Cube : public Shape{
// some code here
};
// Cuboid.h
// #include "Shape.h"
#include "Cube.h" // So here the Shape.h is added to Cube.h and Cube.h is added here.
class Cuboid : public Cube{
// some code here
};
As you can see above the content of Shape.h is added to Cuboid.h indirectly because it is added to Cube.h and cuboid.h includes Cube.h so it is added to it. So without inclusion guards or pragma once if you include the two headers in one source file you get duplicate content there.
I have two functionally identical header files, one of which produces errors for no discernible reason. I must have done something wrong in creating the new (broken) file, but I can't figure out what.
My IDE is Xcode. The project is compiled for Objective C++ using Apple LLVM Compiler 4.1, but the section of code in question is all pure C++, no Objective C.
Here's some code:
NamespaceA.Common.h
#include "../NamespaceB/Common.h"
#include "WorkingClass.h"
#include "BrokenClass.h"
...
../NamespaceB/Common.h
#ifndef NamespaceBCommon
#define NamespaceBCommon
namespace NamespaceB
{
...
}
...
#include "Superclass.h"
...
WorkingClass.h
#ifndef NamespaceA_WorkingClass
#define NamespaceA_WorkingClass
namespace NamespaceA
{
class WorkingClass : public NamespaceB::Superclass
{
public:
WorkingClass();
~WorkingClass();
};
}
#endif
BrokenClass.h
#ifndef NamespaceA_BrokenClass
#define NamespaceA_BrokenClass
// If I don't have this line I get errors. Why?? !!!!!
// This file is exactly identical to WorkingClass.h
// as far as I can tell!
//#include NamespaceA.Common.h
namespace NamespaceA
{
// Parse Issue: Expected class name !!!!!
// Semantic Issue: Use of undeclared identifier 'NamespaceB'
class BrokenClass : public NamespaceB::Superclass
{
public:
BrokenClass();
~BrokenClass();
};
}
#endif
Thank you.
You need to include all of the files that include namespaces and classes that you reference in your code. So, because you reference NamespaceB::Superclass in your BrokenClass.h, you need to be sure to include the file that declares that. In this case, including NamespaceA.Common.h (hopefully) solves this problem, because it includes the file where NamespaceB is included.
As for why you don't have to include NamespaceA.Common.h in your WorkingClass.h, I suspect it's because you just happen to have ../NamespaceB/Common.h included somewhere else.
I found the problem. WorkingClass.cpp was including NamespaceA.Common.h and not including its own header file, rather than including the common file in the header and then including its own header file in the cpp.
I managed to miss the #include in WorkingClass.cpp because I just assumed it was only including WorkingClass.h and not NamespaceA.Common.h.
So in short:
WorkingClass.h
// Class goes here
// No includes
WorkingClass.cpp
// Notice it does not include WorkingClass.h for whatever reason
#include "NamespaceA.Common.h"
NamespaceA.Common.h
#include "../NamespaceB/Common.h"
#include "WorkingClass.h"
#include "BrokenClass.h"
#include "EveryOtherClass.h" ...
BrokenClass.h
// Class goes here
// No includes
BrokenClass.cpp
#include "BrokenClass.h"
// Oh no! Where's NamespaceA.Common.h?
I'm not a big fan of this include scheme, but I'll live with it since it's a large project that I don't want to make sweeping changes to.
#include "DLLDefines.h"
#include "DLLDefines.h"
The above actually passed compilation, but why?
Well, it's legal because it has to be legal. Because you often include the same header multiple times without even realizing it.
You might include two headers in a .cpp file, each of which include a number of files, some of which might be included by both.
For example, all the standard library headers (say, string or vector for example) are probably included in most of your headers. So you quickly end up with the same header being indirectly included multiple times in the same .cpp file.
So in short, it has to work, or all C++ code would fall apart.
As for how it works, usually through include guards. Remember that #include just performs a simple copy/paste: it inserts the contents of the header file at the #include site.
So let's say you have a header file header.h with the following contents:
class MyClass {};
now let's create a cpp file which includes it twice:
#include "header.h"
#include "header.h"
the preprocessor expands this to:
class MyClass {};
class MyClass {};
which obviously causes an error: the same class is defined twice. So that doesn't work. Instead, let's modify the header to contain include guards:
#ifndef HEADER_H
#define HEADER_H
class MyClass {};
#endif
Now, if we include it twice, we get this:
#ifndef HEADER_H
#define HEADER_H
class MyClass {};
#endif
#ifndef HEADER_H
#define HEADER_H
class MyClass {};
#endif
And this is what happens when the preprocessor processes it:
#ifndef HEADER_H // HEADER_H is not defined, so we enter the "if" block
#define HEADER_H // HEADER_H is now defined
class MyClass {};// MyClass is now defined
#endif // leaving the "if" block
#ifndef HEADER_H // HEADER_H *is* defined, so we do *not* enter the "if" block
//#define HEADER_H
//
//class MyClass {};
//
#endif // end of the skipped "if" block
So, the end result is that MyClass got defined only once, even though the header was included twice. And so the resulting code is valid.
This is an important property of header files. Always define your headers so that it is valid to include them multiple times.
It depends on the header file; there is no language restriction on multiple includes of the same file.
Some files are designed to be included multiple times (e.g. <assert.h> can be included multiple times to turn 'on' and 'off' assert).
Many files are safe to be included multiple times because they have include guards, others are not and should be included only once in a translation unit or even a program.
include has nothing to do with the C or C++ language. It is a directive to the preprocessor to bring in a file. The preprocessor doesn't care what file is brought in and it shouldn't. It might be perfectly acceptable to do this:
void Foo::SomeFunc(int cond)
{
switch (cond) {
case kThisCase:
#include "longFirstCase.h"
break;
case kSecondCase:
#include "longSecondCase.h"
break;
case kThirdCase:
#include "longFirstCase.h"
#include "longSecondCase.h"
break;
}
}
I have seen the same file included several times as a configuration mechanism as well.
Granted, there are a number of ways to factor that example that are better, but the point is that there may be perfectly good reasons why you would want to and therefore no restriction on the use.
Probably you have some #define in DLLDefines.h around your code that prevents it from being included twice.
#ifndef DLLDEFINES_H
#define DLLDEFINES_H
// your code
#endif
As long as the multiple inclusion of header files do not violate ODR (One definition Rule) $3.2, the code is well-formed.
It's called an include guard.
#ifndef GRANDFATHER_H
#define GRANDFATHER_H
struct foo {
int member;
};
#endif
Quote from Wikipedia:
In the C and C++ programming languages, an #include guard, sometimes called a macro guard, is a particular construct used to avoid the problem of double inclusion when dealing with the #include directive. The addition of #include guards to a header file is one way to make that file idempotent.
See link above for more information.
DLLDefines.h may also have #pragma once at the
top, #pragma once ensures that file gets included only once.