In A.h I have the following class
class A
{
int a;
char name[100];
}
B.h has the following code
class A;
Class B
{
public:
int c;
float d;
getObjectDetails(A *);
};
I compiled it as g++ A.h B.h B.cpp -o out. But it gives compilation errors saying class A is incomplete. Could any one please help me understand?
Also, if I include header file A.h in B.h, everything goes fine. In that case, I need not declare Class A before Class B definition I think, I can directly create and use instance of class A. Could anyone clarify me on this point?
what happens in step "class A" declaration at compile time and run time?
You can only use forward declarations
with pointers and references (because
these are of a fixed size, independent
of the size of the object they refer
to). If you use a specific class by
value, the compiler needs its full
definition (in order to know its exact
size), thus forward declaration is not
enough.
You can only use forward declarations
for type identification, such as when
you use the declared type in a
function/method pointer parameter
prototype. If you are going to declare
a member variable (i.e. std::string
_name;) the compiler needs a little bit more than a forward declaration
can give it. For example, if someone
does a sizeof(Student) the compiler
has to have access to the entire
declaration to figure out the size.
Answer by Péter Török from this thread.
It should compile fine, if you
1) add a semi-colon at the end of class A declaration.
2) change "C" to "c" in class B declaration.
3) add a return type to getObjectDetails()
The problem is surely in B.cpp, because B.h is fine. If you are trying to do anything with the A* received by getObjectDetails() (such as calling a method on it), the compiler will not be able to understand it.
To fix it, try including A.h in B.cpp (B.h does not need it, indeed).
You probably don't have #include "A.h" in B.cpp, which is then using A in such a way that it requires A to be defined, not just declared. Absent the definition, just about the only thing you can do with the A* passed to getObjectDetails is store it in an A* or void* variable, or pass it on to some other code outside B.cpp.
You should #include A.h from B.h. What you've done instead is called a forward declaration, and is only recommended when A.h either contains an enormous amount of code, or includes other files that do. Then, the "class A;" thing can be a quick way to let your compiler know that A is a class, and hence accept pointers and reference to A objects, without parsing all the extra code from A.h. Your A.h is not long enough to justify such a hack. It is much better to directly use the authoratative source of information about A, which is A.h, instead of spreading information about A (which may one day cease to be true) throughout B. I actively dislike this forward declaration hack, and recommend creating a dedicated forward declaration header that contains "class A;" and any other classes A.h grows to contain, so that uses like B can include that if they don't need the full declarations. This is done by the Standard Library in , which forward declares useful classes, variables and constants for the heavier-weight .
Then, your B.cpp should #include B.h. Your command line should simply be:
g++ B.cpp -o out
(no need to mention A.h or B.h as they will be included (indirectly and directly respectively) from B.cpp.
This code
class A;
class B
{
public:
int c;
float d;
void getObjectDetails(A *);
};
compiles fine for me using VC9 (VS 2008) and I believe this to be correct.
If your code does not compile, it differs from the above in a significant detail. The only way for you to find that (there's no way for us to find it) is to take (a copy of) your original code, and start removing things step by step until the error goes away.
Either you then understand what the problem is or you end up with <20 lines of self-contained example code which reproduce the error - a perfect repro to come back here and ask about.
Related
At this link, the following was mentioned:
add.cpp:
int add(int x, int y)
{
return x + y;
}
main.cpp:
#include <iostream>
int add(int x, int y); // forward declaration using function prototype
int main()
{
using namespace std;
cout << "The sum of 3 and 4 is " << add(3, 4) << endl;
return 0;
}
We used a forward declaration so that the compiler would know what "add" was when compiling main.cpp. As previously mentioned, writing forward declarations for every function you want to use that lives in another file can get tedious quickly.
Can you explain "forward declaration" further? What is the problem if we use it in the main function?
Why forward-declare is necessary in C++
The compiler wants to ensure you haven't made spelling mistakes or passed the wrong number of arguments to the function. So, it insists that it first sees a declaration of 'add' (or any other types, classes, or functions) before it is used.
This really just allows the compiler to do a better job of validating the code and allows it to tidy up loose ends so it can produce a neat-looking object file. If you didn't have to forward declare things, the compiler would produce an object file that would have to contain information about all the possible guesses as to what the function add might be. And the linker would have to contain very clever logic to try and work out which add you actually intended to call, when the add function may live in a different object file the linker is joining with the one that uses add to produce a dll or exe. It's possible that the linker may get the wrong add. Say you wanted to use int add(int a, float b), but accidentally forgot to write it, but the linker found an already existing int add(int a, int b) and thought that was the right one and used that instead. Your code would compile, but wouldn't be doing what you expected.
So, just to keep things explicit and avoid guessing, etc, the compiler insists you declare everything before it is used.
Difference between declaration and definition
As an aside, it's important to know the difference between a declaration and a definition. A declaration just gives enough code to show what something looks like, so for a function, this is the return type, calling convention, method name, arguments, and their types. However, the code for the method isn't required. For a definition, you need the declaration and then also the code for the function too.
How forward-declarations can significantly reduce build times
You can get the declaration of a function into your current .cpp or .h file by #includ'ing the header that already contains a declaration of the function. However, this can slow down your compile, especially if you #include a header into a .h instead of .cpp of your program, as everything that #includes the .h you're writing would end up #include'ing all the headers you wrote #includes for too. Suddenly, the compiler has #included pages and pages of code that it needs to compile even when you only wanted to use one or two functions. To avoid this, you can use a forward-declaration and just type the declaration of the function yourself at the top of the file. If you're only using a few functions, this can really make your compiles quicker compared to always #including the header. For really large projects, the difference could be an hour or more of compile time bought down to a few minutes.
Break cyclic references where two definitions both use each other
Additionally, forward-declarations can help you break cycles. This is where two functions both try to use each other. When this happens (and it is a perfectly valid thing to do), you may #include one header file, but that header file tries to #include the header file you're currently writing... which then #includes the other header, which #includes the one you're writing. You're stuck in a chicken and egg situation with each header file trying to re #include the other. To solve this, you can forward-declare the parts you need in one of the files and leave the #include out of that file.
Eg:
File Car.h
#include "Wheel.h" // Include Wheel's definition so it can be used in Car.
#include <vector>
class Car
{
std::vector<Wheel> wheels;
};
File Wheel.h
Hmm... the declaration of Car is required here as Wheel has a pointer to a Car, but Car.h can't be included here as it would result in a compiler error. If Car.h was included, that would then try to include Wheel.h which would include Car.h which would include Wheel.h and this would go on forever, so instead the compiler raises an error. The solution is to forward declare Car instead:
class Car; // forward declaration
class Wheel
{
Car* car;
};
If class Wheel had methods which need to call methods of Car, those methods could be defined in Wheel.cpp and Wheel.cpp is now able to include Car.h without causing a cycle.
The compiler looks for each symbol being used in the current translation unit is previously declared or not in the current unit. It is just a matter of style providing all method signatures at the beginning of a source file while definitions are provided later. The significant use of it is when you use a pointer to a class as member variable of another class.
//foo.h
class bar; // This is useful
class foo
{
bar* obj; // Pointer or even a reference.
};
// foo.cpp
#include "bar.h"
#include "foo.h"
So, use forward-declarations in classes when ever possible. If your program just has functions( with ho header files), then providing prototypes at the beginning is just a matter of style. This would be anyhow the case had if the header file was present in a normal program with header that has only functions.
Because C++ is parsed from the top down, the compiler needs to know about things before they are used. So, when you reference:
int add( int x, int y )
in the main function the compiler needs to know it exists. To prove this try moving it to below the main function and you'll get a compiler error.
So a 'Forward Declaration' is just what it says on the tin. It's declaring something in advance of its use.
Generally you would include forward declarations in a header file and then include that header file in the same way that iostream is included.
The term "forward declaration" in C++ is mostly only used for class declarations. See (the end of) this answer for why a "forward declaration" of a class really is just a simple class declaration with a fancy name.
In other words, the "forward" just adds ballast to the term, as any declaration can be seen as being forward in so far as it declares some identifier before it is used.
(As to what is a declaration as opposed to a definition, again see What is the difference between a definition and a declaration?)
When the compiler sees add(3, 4) it needs to know what that means. With the forward declaration you basically tell the compiler that add is a function that takes two ints and returns an int. This is important information for the compiler becaus it needs to put 4 and 5 in the correct representation onto the stack and needs to know what type the thing returned by add is.
At that time, the compiler is not worried about the actual implementation of add, ie where it is (or if there is even one) and if it compiles. That comes into view later, after compiling the source files when the linker is invoked.
one quick addendum regarding: usually you put those forward references into a header file belonging to the .c(pp) file where the function/variable etc. is implemented. in your example it would look like this:
add.h:
extern int add(int a, int b);
the keyword extern states that the function is actually declared in an external file (could also be a library etc.).
your main.c would look like this:
#include
#include "add.h"
int main()
{
.
.
.
int add(int x, int y); // forward declaration using function prototype
Can you explain "forward declaration"
more further? What is the problem if
we use it in the main() function?
It's same as #include"add.h". If you know,preprocessor expands the file which you mention in #include, in the .cpp file where you write the #include directive. That means, if you write #include"add.h", you get the same thing, it is as if you doing "forward declaration".
I'm assuming that add.h has this line:
int add(int x, int y);
One problem is, that the compiler does not know, which kind of value is delivered by your function; is assumes, that the function returns an int in this case, but this can be as correct as it can be wrong. Another problem is, that the compiler does not know, which kind of arguments your function expects, and cannot warn you, if you are passing values of the wrong kind. There are special "promotion" rules, which apply when passing, say floating point values to an undeclared function (the compiler has to widen them to type double), which is often not, what the function actually expects, leading to hard to find bugs at run-time.
I am used to do forward declarations of classes like this:
// file 1
#ifndef A_HPP
#define A_HPP
class A
{
...
};
#endif
// file 2
#ifndef B_HPP
#define B_HPP
#ifndef A_HPP
class A;
#endif
class B
{
};
#endif
As you can see in file 2, I try to safe the forward declaration of A. So, it should not be possible to redeclare A.
I have seen a lot of code where they don't put the guards around the forward declarations.
I wanted to know if what I am doing is really necessary or if it adds some kind of safety. Would any of these approaches benefit compilation times more than the other? Which one would you use? Why?
You are NOT adding any safety. Declarations in C++ can be repeated any times you want, as long as they are all coherent.
Furthermore, this is not a good practice. I've never seen someone doing like that. Think what would happen if you move A's definition from a.hpp: you should change all the scope guards around A's forward declaration in all files. Life is already complicated enough.
You dont need to use the marco guard as compiler will know how to process both file.
No need to out the follow 3 lines in file2.h
#ifndef A_HPP
class A;
#endif
use the following line is already good enough
#include "file1.h"
The concept of forward declaration
forward declaration is used to notify compiler there is a class ( or struct or whatever type you want ) named as "A" when reading the file. but compiler knows the declaration is not specific here, but may be in the other file.
At that time, compiler will know:
1) OK, there is a class named as "A", I will remember it.
2) I dont know its size and detail. But if coder use only the A* (pointer of A), it is OK and I dont need to know the detail of A.
Forward declaration is useful. Especially classes are interrelated.
But, if the type name of A is not in sync between both files. g++ will fail to compile.
Compilation time
Forward declaration is also good to use as it save the compilation time.
If the file does not change, g++ will not re-compile again.
While the file 2 use only the forward declaration, so no matter how you change the file 1 or class A, file 2 will not be compile again.
I'm pretty clear on when I can/can't use forward declaration but I'm still not sure about one thing.
Let's say I know that I have to include a header sooner or later to de-reference an object of class A.
I'm not clear on whether it's more efficient to do something like..
class A;
class B
{
A* a;
void DoSomethingWithA();
};
and then in the cpp have something like..
#include "A.hpp"
void B::DoSomethingWithA()
{
a->FunctionOfA();
}
Or might I as well just include A's header in B's header file in the first place?
If the former is more efficient then I'd appreciate it if someone clearly explained why as I suspect it has something to do with the compilation process which I could always do with learning more about.
Use forward declarations (as in your example) whenever possible. This reduces compile times, but more importantly minimizes header and library dependencies for code that doesn't need to know and doesn't care for implementation details. In general, no code other than the actual implementation should care about implementation details.
Here is Google's rationale on this: Header File Dependencies
When you use forward declaration, you explicitly say with it "class B doesn't need to know anything about internal implementation of class A, it only needs to know that class named A exists". If you can avoid including that header, then avoid it. - it's good practice to use forward declaration instead because you eliminate redundant dependencies by using it.
Also note, that when you change the header file, it causes all files that include it to be recompiled.
These questions will also help you:
What are the drawbacks of forward declaration?
What is the purpose of forward declaration?
Don't try to make your compilation efficient. There be dragons. Just include A.hpp in B.hpp.
The standard practice for C and C++ header files is to wrap all of the header file in an #ifndef to make sure it is compiled only once:
#ifndef _A_HPP_
#define _A_HPP_
// all your definitions
#endif
That way, if you #include "A.hpp" in B.hpp, you can have a program that includes both, and it won't break because it won't try to define anything twice.
At this link, the following was mentioned:
add.cpp:
int add(int x, int y)
{
return x + y;
}
main.cpp:
#include <iostream>
int add(int x, int y); // forward declaration using function prototype
int main()
{
using namespace std;
cout << "The sum of 3 and 4 is " << add(3, 4) << endl;
return 0;
}
We used a forward declaration so that the compiler would know what "add" was when compiling main.cpp. As previously mentioned, writing forward declarations for every function you want to use that lives in another file can get tedious quickly.
Can you explain "forward declaration" further? What is the problem if we use it in the main function?
Why forward-declare is necessary in C++
The compiler wants to ensure you haven't made spelling mistakes or passed the wrong number of arguments to the function. So, it insists that it first sees a declaration of 'add' (or any other types, classes, or functions) before it is used.
This really just allows the compiler to do a better job of validating the code and allows it to tidy up loose ends so it can produce a neat-looking object file. If you didn't have to forward declare things, the compiler would produce an object file that would have to contain information about all the possible guesses as to what the function add might be. And the linker would have to contain very clever logic to try and work out which add you actually intended to call, when the add function may live in a different object file the linker is joining with the one that uses add to produce a dll or exe. It's possible that the linker may get the wrong add. Say you wanted to use int add(int a, float b), but accidentally forgot to write it, but the linker found an already existing int add(int a, int b) and thought that was the right one and used that instead. Your code would compile, but wouldn't be doing what you expected.
So, just to keep things explicit and avoid guessing, etc, the compiler insists you declare everything before it is used.
Difference between declaration and definition
As an aside, it's important to know the difference between a declaration and a definition. A declaration just gives enough code to show what something looks like, so for a function, this is the return type, calling convention, method name, arguments, and their types. However, the code for the method isn't required. For a definition, you need the declaration and then also the code for the function too.
How forward-declarations can significantly reduce build times
You can get the declaration of a function into your current .cpp or .h file by #includ'ing the header that already contains a declaration of the function. However, this can slow down your compile, especially if you #include a header into a .h instead of .cpp of your program, as everything that #includes the .h you're writing would end up #include'ing all the headers you wrote #includes for too. Suddenly, the compiler has #included pages and pages of code that it needs to compile even when you only wanted to use one or two functions. To avoid this, you can use a forward-declaration and just type the declaration of the function yourself at the top of the file. If you're only using a few functions, this can really make your compiles quicker compared to always #including the header. For really large projects, the difference could be an hour or more of compile time bought down to a few minutes.
Break cyclic references where two definitions both use each other
Additionally, forward-declarations can help you break cycles. This is where two functions both try to use each other. When this happens (and it is a perfectly valid thing to do), you may #include one header file, but that header file tries to #include the header file you're currently writing... which then #includes the other header, which #includes the one you're writing. You're stuck in a chicken and egg situation with each header file trying to re #include the other. To solve this, you can forward-declare the parts you need in one of the files and leave the #include out of that file.
Eg:
File Car.h
#include "Wheel.h" // Include Wheel's definition so it can be used in Car.
#include <vector>
class Car
{
std::vector<Wheel> wheels;
};
File Wheel.h
Hmm... the declaration of Car is required here as Wheel has a pointer to a Car, but Car.h can't be included here as it would result in a compiler error. If Car.h was included, that would then try to include Wheel.h which would include Car.h which would include Wheel.h and this would go on forever, so instead the compiler raises an error. The solution is to forward declare Car instead:
class Car; // forward declaration
class Wheel
{
Car* car;
};
If class Wheel had methods which need to call methods of Car, those methods could be defined in Wheel.cpp and Wheel.cpp is now able to include Car.h without causing a cycle.
The compiler looks for each symbol being used in the current translation unit is previously declared or not in the current unit. It is just a matter of style providing all method signatures at the beginning of a source file while definitions are provided later. The significant use of it is when you use a pointer to a class as member variable of another class.
//foo.h
class bar; // This is useful
class foo
{
bar* obj; // Pointer or even a reference.
};
// foo.cpp
#include "bar.h"
#include "foo.h"
So, use forward-declarations in classes when ever possible. If your program just has functions( with ho header files), then providing prototypes at the beginning is just a matter of style. This would be anyhow the case had if the header file was present in a normal program with header that has only functions.
Because C++ is parsed from the top down, the compiler needs to know about things before they are used. So, when you reference:
int add( int x, int y )
in the main function the compiler needs to know it exists. To prove this try moving it to below the main function and you'll get a compiler error.
So a 'Forward Declaration' is just what it says on the tin. It's declaring something in advance of its use.
Generally you would include forward declarations in a header file and then include that header file in the same way that iostream is included.
The term "forward declaration" in C++ is mostly only used for class declarations. See (the end of) this answer for why a "forward declaration" of a class really is just a simple class declaration with a fancy name.
In other words, the "forward" just adds ballast to the term, as any declaration can be seen as being forward in so far as it declares some identifier before it is used.
(As to what is a declaration as opposed to a definition, again see What is the difference between a definition and a declaration?)
When the compiler sees add(3, 4) it needs to know what that means. With the forward declaration you basically tell the compiler that add is a function that takes two ints and returns an int. This is important information for the compiler becaus it needs to put 4 and 5 in the correct representation onto the stack and needs to know what type the thing returned by add is.
At that time, the compiler is not worried about the actual implementation of add, ie where it is (or if there is even one) and if it compiles. That comes into view later, after compiling the source files when the linker is invoked.
one quick addendum regarding: usually you put those forward references into a header file belonging to the .c(pp) file where the function/variable etc. is implemented. in your example it would look like this:
add.h:
extern int add(int a, int b);
the keyword extern states that the function is actually declared in an external file (could also be a library etc.).
your main.c would look like this:
#include
#include "add.h"
int main()
{
.
.
.
int add(int x, int y); // forward declaration using function prototype
Can you explain "forward declaration"
more further? What is the problem if
we use it in the main() function?
It's same as #include"add.h". If you know,preprocessor expands the file which you mention in #include, in the .cpp file where you write the #include directive. That means, if you write #include"add.h", you get the same thing, it is as if you doing "forward declaration".
I'm assuming that add.h has this line:
int add(int x, int y);
One problem is, that the compiler does not know, which kind of value is delivered by your function; is assumes, that the function returns an int in this case, but this can be as correct as it can be wrong. Another problem is, that the compiler does not know, which kind of arguments your function expects, and cannot warn you, if you are passing values of the wrong kind. There are special "promotion" rules, which apply when passing, say floating point values to an undeclared function (the compiler has to widen them to type double), which is often not, what the function actually expects, leading to hard to find bugs at run-time.
I'm using #pragma once, not #include guards on all my h files. What do I do if a.h needs to #include b.h and b.h needs to #include a.h?
I'm getting all sorts if errors because by doing this, the pragma once takes effect and one of them is missing each other. How should I do this.
Thanks
You need to forward declare the definitions you need. So if A uses B as a parameter value, you need to forward declare B, and vice versa.
It could be that just forward declaring the class names:
class A;
class B;
solves your problems.
The accepted answer to this question provides some additional guidance.
One possibility is to refactor some portion of the files a.h and b.h into a third file say c.h, and include it from both a.h and b.h. This way, the latter two would no longer need to mutually include each other.
Another possibility is to merge the separate header files into one.
A third possibility is the situation when two classes legitimately need to refer to each other. In such cases you have to use pointers. Moreover, you can forward declare the class instead of including its header file. [Mentioned also by jdv] For example,
// file a.h
struct B;
struct A { B * b_ };
// file b.h
struct A;
struct B { A * a_; };
However, without knowing your particular situation it is difficult to provide specific suggestion.
It depends on what is needed from each other's header file. IF it's a class definition, but it only is using a pointer to the class, then instead of including the head file just put in a forward declaration like:
class MyClassA;
The solution for this issue is 'forward declaration'.
If you have a class or a function that needs to be used in 2 headers one of the headers needs to forward declare the used class or type.
Or you need to consider to restructure your headers.
This is a common beginner issue that circular dependencies are causing such issues. If you google on 'forward declaration' will find tons of results.
Since your question was too unspecific I can't give you an exact answer, sorry for this.
You can not use incomplete types, but you can just forward declare them. You just tell the compiler:"Don't get syntax errors, I know what i am doing". Which means that the linker will go and find complete types from libraries whatsoever.