C++ Header #define compiler error - c++

I'm learning C++ and I'm at a fairly low level still. - I'm currently looking at using header files and I have a two part question.
Part 1
As I understand them so far, header file definitions are similar to hard coded strings within VB.net? For example I can do the following #define STOCK_QUANTITY 300 and then reference my definition when using it within functions? I assume this works the same way as VB.net strings as I only need to change the value in one place should I need to make changes to the definition and my program references the number 300 on a few hundred different lines?
Part 2
Now, as I said I'm still learning so I'm still doing ye old multiplication tasks. I'm good within using functions with my main .cpp file but I'm not moving on to header files. This is my code snippet thus far.
add.h
#ifndef ADD_H
#define ADD_H
int add(int x, int y);
#endif
main.cpp
#include "stdafx.h"
#include <iostream>
#include "add.h"
int main()
{
using namespace std;
cout << add(3, 4) << endl;
return 0;
}
When trying to run this I receive 2 build errors and it will not compile.
Apologies is these are silly questions, but I would appreciate insight, tips or even some other things I should consider. Thanks.
EDIT
Based on an answer I've changed my add.h too
#ifndef ADD_H
#define ADD_H
int add(int x, int y)
{
return x + y;
}
#endif
As soon as I read the answer I realised I hadn't even told the function what to do :( - Gosh.

You have not added a function body for the function add
int add(int x, int y)
{
// add stuff here
}
This can be done in either the header file, or a seperate cpp file for add. You are trying to call the function that has no code. This is known as a function prototype.

You have only declared that the function add exists, which is why you can call it. But you don't actually define the function anywhere.
In C++ you have to differ between declaration and definition. Sometimes those are done at the same time, like when declaring a local variable. Other times you separate them, like when having a function prototype in a header file (like you do) then that's the declaration. The definition of the function is then the implementation of the function.
After the edit, you now have another problem. And that is if you include the header file in multiple source files, each of those source files (formally known as translation units) will have the function defined and you will get an error because of that.
It can be solved by making the function static or inline. Or better yet, create a new source file (like add.cpp) where you have the definition of the add function, and keep only the declaration (prototype) in the header file.

As for part 1 of your question:
While #defines do as you described, there are some of disadvantages with using them (e.g. They are parsed by the pre-processor, and not by the compiler so no type checking, and also you can get funky errors if you have slightly more complicated macros.
So while your statement is valid, in that it defines a global constant that you only need to modify in one place, and can use in multiple places, for that purpose it is better to have an actual constant variable in the header file:
e.g.
const int STOCK_QUANTITY = 300;
Now you explicitly name it an integer, and also the compiler can perform extra checking.
See also Item 3 in Effective C++ by Scott Meyer (which is a must read in my opinion if you are serious about contineouing programming in c++, although you need allready some experience before reading that.)

Related

Is it possible to use a class in a header file without including it, while also using that same class in the cpp file? [duplicate]

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.

C++ class header files and include [duplicate]

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 having an 2D Array Redefinition Error

There is an error (actually 3 same errors) with my definition array int mang[max][max] and I couldn't find anything to fix it properly, so I hope someone will notice my question and help me soon. XD
In my header file array.h, I have:
#include <iostream>
#define max 100
using namespace std;
int mang[max][max];
void NhapMang(int mang[][max], int hang, int cot);
void XuatMang(int mang[][max], int hang, int cot);
int TinhTongPhanTu(int mang[][max], int hang, int cot);
int DemPhanTux(int mang[][max], int hang, int cot);
When I was typing my code, VS shows me that there is "no issues found" all over .cpp files, but when I debug the code, the error appears in the header file array.h, says "C2086 'int mang[100][100]': redefinition" altogether.
I think that I've defined mang twice or more, but I couldn't find the other mang definition nor fixing it if I found. This is the capture of the error list.
I don't know what parts I need provide to you in my project to help fixing it for me (and I also think my post would become so long to read if I copy-paste all my code up here :-( ), so if you need any further information, just comment and I will give it to you.
And well, I've just start learning C++ for 3 months, so there's soooo many things I haven't known yet XD If there's anything I couldn't understand in the way you fix the problem, please let me ask you more about it.
Hope you understand what I mean XD (cuz I'm not a native speaker). And thank you for reading.
The language rules say:
[basic.def.odr]
Every program shall contain exactly one definition of every non-inline function or variable that is odr-used in that program outside of a discarded statement; no diagnostic required. ...
(There are some exceptions with limitations that are listed in further rules, but none that apply to your example)
int mang[max][max];
This is definition of a variable. That definition is in a header file. Header files are typically included into multiple translation units. If you do so, then you have included the definition of the variable into multiple translation units. By having multiple definitions of a non-inline variable, you would violate the rule quoted above.
The key here is that the pre-processor is a text altering engine. In every file where you have #include "array.h", the textual contents of array.h are inserted in place of the #include.
So, if you have several files that include array.h then each one of those files declares and defines mang (all using the same definition). That isn't a problem during compilation because each file is compiled separately, but they each generate an object file that defines mang.
Then you try to link, and the linker sees several defitions of the array.
The solution is the same as the one you are using for functions in array.h: you declare in the header and define in the implementation (presumably array.cpp).
How do you declare an array without defining it?
Good question. I'm glad you asked. You do it with the extern keyword like this.
array.h:
// ...
#define max 100
extern int mang[max][max]; // <=== Look here (with extern)
// ...
Then you define it in array.cpp:
// ...
int mang[max][max]; // <== and compare to this (no extern)
// ..
As an aside you using the pre-processor to define constants (like #define max 100 has several downsides, and in c++ you are generally better off using compile-time constants like
const int max = 100; // Pre c++11
or
constexpr int max = 100; // c++11 or later
(The use of the pre-processor for this is a holdover from ancient days when compilers were a lot less clever.)

How do i introduce 3 functions at once? [duplicate]

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.

State Pattern in C++ with undefined variables [duplicate]

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.