I'm working in a project with several classes. All header files are into "include" folder, and all src files in another folder. But at this point, a class that has been working without problems is missing.
The code that produce the error is:
namespace render{
class CSprite2D
{
CTexture * m_texture;
And the error is syntax error : missing ';' before '*'
So I don't have any idea about why VC++ don't find my class. The order in wich VC++ compile classes is very estrange: detects error in sprite2D before to try to compile Texture.cpp. Also, CTexture class has been into the project, and running perfectly before the creation of sprite2D.
Could you help me with some trick to find error?
*Edit:*It works, and the solution is to simply forward declaring the texture class (thanks to James and peenut). But now my doubt is: if I've included the texture, why do I need to forward declare texture class? It is not enough to include the header file?
Thanks in advance.
just declare it, you use only pointer:
namespace render{
class CTexture; //forward declaration
class CSprite2D
{
CTexture * m_texture;
Of course, as comments suggets:
don't forget to include all necessary headers in your *.cpp files
use forward declarations to break-up circular dependencies (e.g. class A { B * b; }; class B { A * a; })
Edit: Asker's edit:
I've included the texture, why do I need to forward declare texture class?
Imagine you have "sprite.hpp", "texture.hpp", and CSprite2D contains pointer to texture. Without forward declaration you have to include "texture.hpp" always before including "sprite.hpp". Even worse, if your CTexture uses pointer to CSprite2D, you have no other choice but to use forward declaration to avoid cyclic dependencies.
If the header file that code is located in doesn't include anything that eventually contains a definition for CTexture, it won't know what a CTexture is even if other places do.
However, since you are only using a pointer here, you could probably just do a forward declaration and include the header in the .cpp file where the methods / data of CTexture are used to avoid cyclical header includes.
Related
When I started learning C++ I learned that header files should typically be #included in other header files. Just now I had someone tell me that I should include a specific header file in my .cpp file to avoid header include creep.
Could someone tell me what exactly that is, why it is a problem and maybe point me to some documentation on when I would want to include a file in another header and when I should include one in a .cpp file?
The "creep" refers to the inclusion of one header including many others. This has some unwanted consequences:
a tendency towards every source file indirectly including every header, so that a change to any header requires everything to be recompiled;
more likelihood of circular dependencies causing heartache.
You can often avoid including one header from another by just declaring the classes you need, rather than including the header that gives the complete definition. Such an incomplete type can be used in various ways:
// Don't need this
//#include "thingy.h"
// just this
class thingy;
class whatsit {
// You can declare pointers and references
thingy * p;
thingy & r;
// You can declare static member variables (and external globals)
// They will need the header in the source file that defines them
static thingy s;
// You can declare (but not define) functions with incomplete
// parameter or return types
thingy f(thingy);
};
Some things do require the complete definition:
// Do need this
#include "thingy.h"
// Needed for inheritance
class whatsit : thingy {
// Needed for non-static member variables
thingy t;
// Needed to do many things like copying, accessing members, etc
thingy f() {return t;}
};
Could someone tell me what exactly [include creep] is
It's not a programming term, but interpreting it in an Engish-language context would imply that it's the introduction of #include statements that are not necessary.
why it is a problem
Because compiling code takes time. So compiling code that's not necessary takes unnecessary time.
and maybe point me to some documentation on when I would want to include a file in another header and when I should include one in a .cpp file?
If your header requires the definition of a type, you will need to include the header that defines that type.
#include "type.h"
struct TypeHolder
{
Type t;
// ^^^^ this value type requires the definition to know its size.
}
If your header only requires the declaration of a type, the definition is unnecessary, and so is the include.
class Type;
struct TypeHolder
{
Type * t;
// ^^^^^^ this pointer type has the already-known size of a pointer,
// so the definition is not required.
}
As an anecdote that supports the value of this practice, I was once put on a project whose codebase required ONE HOUR to fully compile. And changing a header often incurred most or all of that hour for the next compilation.
Adding forward-declarations to the headers where applicable instead of includes immediately reduced full compilation time to 16 minutes, and changing a header often didn't require a full rebuild.
Well they were probably referring to a couple of things ("include creep" is not a term I've ever heard before). If you, as an extreme rule, only include headers from headers (aside from one matching header per source file):
Compilation time increases as many headers must be compiled for all source files.
Unnecessary dependencies increase, e.g. with a dependency based build system, modifying one header may cause unnecessary recompilation of many other files, increasing compile time.
Increased possibility of namespace pollution.
Circular dependencies become an issue (two headers that need to include each other).
Other more advanced dependency-related topics (for example, this defeats the purpose of opaque pointers, which causes many design issues in certain types of applications).
As a general rule of thumb, include the bare minimum number of things from a header required to compile only the code in that header (that is, enough to allow the header to compile if it is included by itself, but no more than that). This will combat all of the above issues.
For example, if you have a source file for a class that uses std::list in the code, but the class itself has no members or function parameters that use std::list, there's no reason to #include <list> from the class's header, as nothing in the class's header uses std::list. Do it from the source file, where you actually need it, instead of in the header, where everything that uses the class also has to compile <list> unnecessarily.
Another common technique is forward declaring pointer types. This is the only real way to combat circular dependency issues, and has some of the compilation time benefits listed above as well. For example, if two classes refer to each other but only via pointers:
// A.h
class B; // forward declaration instead of #include "B.h"
class A {
B *b;
}
// B.h
class A; // forward declaration instead of #include "A.h"
class B {
A *a;
}
Then include the headers for each in the source files, where the definitions are actually needed.
Your header files should include all headers they need to compile when included alone (or first) in a source file. You may in many cases allow the header to compile by using forward declarations, but you should never rely on someone including a specific header before they include yours.
theres compie time to think of, but there's also dependancies. if A.h includes B.h and viceversa, code won't compile. You can get around this by forward referancing your class, then including the header in the cpp
A.h
class B;
class A
{
public:
void CreateNewB():
private:
B* m_b;
};
A.cpp
#include "B.h"
A::CreateNewB()
{
m_b = new B;
}
I am getting this compiler error
error: 'RawLog' does not name a type
Here is the relevant code:
//DataAudit.h
#ifndef DATAAUDIT_H
#define DATAAUDIT_H
class RawLog;
class DataAudit
{
...
private:
RawLog* _createNewRawLog(); // This is the line indicated with the error
};
#endif // DATAAUDIT_H
Usually a forward declaration resolves this kind of error. This answer indicates that a circular header inclusion may cause this. But doesn't the use of the #ifndef and #define statements prevent circular header inclusion?
Is there another reason I might see this error?
What are some avenues of approach I could use to further deduce the nature of this error?
Update: This is rather odd. I have a Globals.h file, and if I define a new enum in Globals.h, the error appears. Then if I comment out the enum, the error goes away. This leads me to think that the circular dependency has existed for a while, and adding the enum somehow re-orders the compilation units, thus exposing the dependency that wasn't there before?
The #ifndef header guard doesn't prevent circular dependencies. It just prevents multiple inclusions of the same header in a single file.
Looks like a circular dependency to me. This means you #include a header in DataAudit.h that #includes DataAudit.h either directly or indirectly.
In the end, I am not sure I understand completely why the error occurred, but this is what I did to resolve it, and some other related information. Maybe this will help others that come across this question.
For each header file in my project
For each #include "..." in the header
If there are no references to the class in the #include, remove it.
If there are only pointers to the class defined in the #include, then replace it with a class ... forward declaration.
If there is a member instance of the class defined in #include and it makes sense to use a pointer and allocate the member on the heap, then change the member to a pointer, and replace the #include with a class .... forward declaration.
Go through my Globals.h and move anything that can be moved out of it to more localized and specific header files.
Specifically, remove an enum that was defined is Globals.h, and place it in a more localized header file.
After doing all this I was able to make the error go away. Strangely enough, the enum in Globals.h seemed to be a catalyst for the error. Whenever I removed it from Globals.h, the error would go away. I don't see how this enum could cause the error, so I think it indirectly led to the error somehow. I still wasn't able to figure out exactly how or why, but it has helped me for this guideline when coding in C++:
Don't put anything in a header file unless it needs to be there. Don't
place anything in a Globals.h that can be placed in a more localized
file. Basically, do all you can to reduce the amount of code that is
included through the #include directives.
I have a big game engine to compile and it worked fine until I did some crazy adjustments. The compiler somehow cannot reconize my mean Game object and produce error C2061: syntax error : identifier 'Game', and it seems no matter what file I compile the error always points to a file called GameDataLoader.h even there is absolutely no connection with this two files. Usually I think it is an inclusion problem but the fact is I have Game.h included in every .h file necessary, right after the inclusion of stdafx.h and I have #pragama once on top of it. I thought about circular inclusion problem but the #pragma once should take care of that. Plus this inclusion directives works fine until I changed some file name and other messy stuff. I cleaned the entire solution and tried to rebuild it but still no luck (using VS2012).
I don't know if showing the code will help, but here is the code for gameDataLoader.h. This isn't a file I wrote but it should work properly.
#pragma once
#include "stdafx.h"
#include "Game\Game.h" // Game.h included
class GameDataLoader
{
public:
GameDataLoader(){}
~GameDataLoader(){}
void GameDataLoader::loadGameProperties( Game *game, map<wstring, wstring> *properties, wstring gameInitFile);
virtual void loadGame(Game *game, wstring gameInitFile) = 0;
virtual void loadGUI(Game *game, wstring guiInitFile) = 0;
virtual void loadWorld(Game *game, wstring levelInitFile) = 0;
};
And I had errors exactly on those 4 lines with Game object. What could possibly be the problem?
Double inclusion? Circular inclusion? Or did not include something and somewhere else?
Most likely, Game.h is including GameDataLoader.h, either directly or indirectly, creating a circular dependency; but you forgot to show us Game.h, so I can't be sure of that.
If that is the case, then #pragma once (or the equivalent include guard) will mean that one of the headers will be included before the other, and declarations from the second won't be available to the first. It won't magically include both of them before each other, since that is impossible.
Luckily, GameDataLoader.h doesn't need the full definition of Game, since it only deals with pointers to it. So you can remove the inclusion of Game.h and just declare class Game; instead.
So, thanks to this website, I found the answer to my previous problem. I'm adding a function to a class in a GNU automake project that uses a pointer to a doc object. Dependencies were included in the Makefile.am file to include doc.h and plsa.h in the respective order. However, when I compiled, I would get a doc has not been declared error. Then, I tried adding the #include statement here, which gives a previous redefinition of 'class doc' error.
I learned that I have to declare doc by using the class doc; line commented out below; however, I thought that this was only necessary if I was declaring a function that passes the object by value. Can someone explain to me why the #include is incorrect in this case?
#include "doc.h"
//class doc;
class plsa {
// ...
int infer(doc *trset, int maxiter, double noiseH);
}
Why the Redefinition errors?
Please ensure that your header files have appropriate Header Guards/Include Guards.It is most likely that you have missed adding header guards and hence that causes multiple class definitions due to the header getting included multiple times.
Why Forward Declaration is okay in this case?
When instead of including the header file you add the line:
class doc;
It Forward declares the class doc which means for compiler it is an Incomplete type. With Incomplete types, One cannot create objects of it or do anything which needs the compiler to know the layout of docor more than the fact that doc is just an type.
i.e: The compiler does not know what are its members and what its memory layout is.
But Since pointers to all objects need just the same memory allocation, You can use the forward declaration when just reffering to an Incomplete type as a pointer.
In this case the only way in which doc is being referenced is an pointer to the class doc and hence the Forward declaration will work as well.
BottomLine:
Including the header file should work for you If you have proper Inclusion Guards in-place.
And there is nothing wrong with it.
However, Forward declaring the class should also work for you because of the reasoning given above.Note that forward declarations are usually used in case where there is a Circular Dependency of classes.
Which is better Include header File or Forward Declaration?
Including the header file just copy pastes the code from the header to wherever the file was included, which basically could lead to:
Increase in compilation time
Pollution of global namespace.
Potential clash of preprocessor names.
Increase in Binary size(in some cases though not always)
Forward Declaration has its own limitations on how the Incomplete type can be used further on.
With Incomplete type you can:
Declare a member to be a pointer or a reference to the incomplete type.
Declare functions or methods which accepts/return incomplete types.
Define functions or methods which accepts/return pointers/references to the incomplete type (but without using its members).
With Incomplete type you cannot:
Use it as a base class.
Use it to declare a member.
Define functions or methods using this type.
Given the possibility(due to above limitations on Incomplete type usage) One should prefer Forward Declaration over Including Header.
You are missing include guardians. if you just include files they are just pasted you need to make sure when they are included multiple times that they other times the code isn't duplicated. so you use a construct like this.
#ifndef _XXX_
#define _XXX_
/* your header here */
#endif
In my C++ project when do I have to use inclusion (#include "myclass.h") of header files? And when do I have to use forward declaration of the class (class CMyClass;)?
As a rule try the forward declaration first. This will reduce compile times etc. If that doesn't compile go for the #include. You have to go for the #include if you need to do any of the following:
Access a member or function of the class.
Use pointer arithmetic.
Use sizeof.
Any RTTI information.
new/delete, copy etc.
Use it by value.
Inherit from it.
Have it as a member.
Instance in a function.
(6,7,8,9 from #Mooing Duck)
They're are probably more but I haven't got my language law hat on today.
There are several problems to forward declaration:
It is like storing your class name in multiple places -- if you change it in one place, you now have to change it everywhere else. Refactoring becomes a challenge since the code will still compile fine with the changed class name, but linking will fail since the forward declarations refer to an undefined class. If you include the header file and do not use forward declarations, you will catch these problems during compilation.
Forward declarations are difficult for others to maintain. For instance, if a header file contains:
include "MyProject/MyWidgets/MyFooWidgets/FooUtil/Foo.h"
rather than the forward declaration
class Foo ;
it is easy for others to find where the class Foo is declared. With forward declaration, it is not that
obvious; some IDEs like Eclipse may open the forward declaration when the user tries to open
the declaration of a variable.
Linking can fail with undefined symbol errors when you include a header file in your code that contains a forward declaration but the actual code definition is located in some other library that you did not link with. It's more convenient to catch this problem at compile time with errors like "Could not find file MyProject/MyWidgets/MyFooWidgets/FooUtil/Foo.h" since then you will know where to look for the corresponding Foo.cpp and identify the library that contains it.
If you think your build is taking too long, then try doing a compile only with no link. If your code takes 10 seconds to compile and 10 minutes to link, the problem has nothing to do with a few extra includes. Similarly, if your header file contains so much stuff in it that it is actually causing a performance problem then it is probably time for you to refactor the content of that file into multiple smaller header files.
So when is it OK to forward declare? If you do it in the same header file as the real declaration.
Example:
class Foo ;
typedef Foo* FooPtr ;
typedef Foo& FooRef ;
class Foo
{
public:
Foo( ) ;
~Foo( ) ;
}
OR
class TreeNode ;
class Tree
{
private:
TreeNode m_root ;
}
class TreeNode
{
void* m_data ;
} ;
If you only need a pointer to the class and you don't need any knowledge about the class rather than its name, you can use the forward declaration.
As a beginner, you should always #include header files when you need to use the types or functions they contain - do not try to "optimise" your build by forward declaring things - this is hardly ever necessary, even on large projects, provided the project is well architected.
The only time you absolutely need a forward declaration is in situations like this:
struct A {
void f( B b );
};
struct B {
void f( A a );
};
where each struct (or class) refers to the type of the other. In this case, you need a forward declaration of B to resolve the issue:
struct B; // forward declaration
struct A {
void f( B b );
};
struct B {
void f( A a );
};
You should strive towards minimizing your #includes both in order to reduce compilation times but also to help with modularity and testability. As #ypnos says, class forwards are excellent when you only need pointers.
For some practical tips on how to reduce header dependencies, see e.g. this article.