This question already has answers here:
Is it a good practice to place C++ definitions in header files?
(17 answers)
Closed 2 years ago.
I'm wondering if it's a good practice to store C++ regular functions, not methods(the ones in classes) inside header files.
Example:
#ifndef FUNCTIONS_H_INCLUDED
#define FUNCTIONS_H_INCLUDED
int add(int a, int b)
{
return a + b;
}
#endif
And Use it like this:
#include <iostream>
#include "Functions.h"
int main(int argc, char* args[])
{
std::cout << add(5, 8) << std::endl;
return 1;
}
Is this a good a good practice?
Thanks in advance!
If you want to use a function in multiple source files (or rather, translation units), then you place a function declaration (i.e. a function prototype) in the header file, and the definition in one source file.
Then when you build, you first compile the source files to object files, and then you link the object files into the final executable.
Example code:
Header file
#ifndef FUNCTIONS_H_INCLUDED
#define FUNCTIONS_H_INCLUDED
int add(int a, int b); // Function prototype, its declaration
#endif
First source file
#include "functions.h"
// Function definition
int add(int a, int b)
{
return a + b;
}
Second source file
#include <iostream>
#include "functions.h"
int main()
{
std::cout << "add(1, 2) = " << add(1, 2) << '\n';
}
How you build it depends very much on your environment. If you are using an IDE (like Visual Studio, Eclipse, Xcode etc.) then you put all files into the project in the correct places.
If you are building from the command line in, for example, Linux or OSX, then you do:
$ g++ -c file1.cpp
$ g++ -c file2.cpp
$ g++ file1.o file2.o -o my_program
The flag -c tells the compiler to generate an object file, and name it the same as the source file but with a .o suffix. The last command links the two object files together to form the final executable, and names it my_program (that's what the -o option does, tells the name of the output file).
No. After preprocessing, each source file will contain the header file. Then, at the linking stage you will end up with a multiple definition error because you will have multiple definitions of the same function.
Using inline or static will get rid of the linking error. Unless you want the function to be inline, it is best to declare the function in the header and define it in a single source file and link it.
If you declare the function as inline, then each of its function call in the source file will be replaced with the code inside the inlined function. So, there's no extra symbol defined.
If you declare the function as static, then the function symbol will not be exported from the translation unit. Therefore, no duplicate symbols.
Adding to what is said above, a function defined entirely inside a class/struct/union definition, whether it's a member function or a non-member friend function , is implicitly an inline function. So you do not need to explicitly write inline for the mentioned situations.
No. If you import the same header from two files, you get redefinition of function.
However, it's usual if the function is inline. Every file needs it's definition to generate code, so people usually put the definition in header.
Using static also works because of fact that static functions are not exported from object file and in this way can't interfere with other functions with the same name during linkage.
It's also OK to define member functions inside the class in header as C++ standard considers them as inline.
Related
This question already has answers here:
Is it a good practice to place C++ definitions in header files?
(17 answers)
Closed 2 years ago.
I'm wondering if it's a good practice to store C++ regular functions, not methods(the ones in classes) inside header files.
Example:
#ifndef FUNCTIONS_H_INCLUDED
#define FUNCTIONS_H_INCLUDED
int add(int a, int b)
{
return a + b;
}
#endif
And Use it like this:
#include <iostream>
#include "Functions.h"
int main(int argc, char* args[])
{
std::cout << add(5, 8) << std::endl;
return 1;
}
Is this a good a good practice?
Thanks in advance!
If you want to use a function in multiple source files (or rather, translation units), then you place a function declaration (i.e. a function prototype) in the header file, and the definition in one source file.
Then when you build, you first compile the source files to object files, and then you link the object files into the final executable.
Example code:
Header file
#ifndef FUNCTIONS_H_INCLUDED
#define FUNCTIONS_H_INCLUDED
int add(int a, int b); // Function prototype, its declaration
#endif
First source file
#include "functions.h"
// Function definition
int add(int a, int b)
{
return a + b;
}
Second source file
#include <iostream>
#include "functions.h"
int main()
{
std::cout << "add(1, 2) = " << add(1, 2) << '\n';
}
How you build it depends very much on your environment. If you are using an IDE (like Visual Studio, Eclipse, Xcode etc.) then you put all files into the project in the correct places.
If you are building from the command line in, for example, Linux or OSX, then you do:
$ g++ -c file1.cpp
$ g++ -c file2.cpp
$ g++ file1.o file2.o -o my_program
The flag -c tells the compiler to generate an object file, and name it the same as the source file but with a .o suffix. The last command links the two object files together to form the final executable, and names it my_program (that's what the -o option does, tells the name of the output file).
No. After preprocessing, each source file will contain the header file. Then, at the linking stage you will end up with a multiple definition error because you will have multiple definitions of the same function.
Using inline or static will get rid of the linking error. Unless you want the function to be inline, it is best to declare the function in the header and define it in a single source file and link it.
If you declare the function as inline, then each of its function call in the source file will be replaced with the code inside the inlined function. So, there's no extra symbol defined.
If you declare the function as static, then the function symbol will not be exported from the translation unit. Therefore, no duplicate symbols.
Adding to what is said above, a function defined entirely inside a class/struct/union definition, whether it's a member function or a non-member friend function , is implicitly an inline function. So you do not need to explicitly write inline for the mentioned situations.
No. If you import the same header from two files, you get redefinition of function.
However, it's usual if the function is inline. Every file needs it's definition to generate code, so people usually put the definition in header.
Using static also works because of fact that static functions are not exported from object file and in this way can't interfere with other functions with the same name during linkage.
It's also OK to define member functions inside the class in header as C++ standard considers them as inline.
I'm just testing out how extern works (using MSVC) and I cannot get it to work, no matter what I do:
// Test.h
int externalint = 10
// Main.cpp
void main()
{
extern int externalint;
std::cout << externalint << std::endl;
std::cin.ignore();
}
This results in a linking error, even though I defined it in the header. I do not wish to include the header because the way I read it says it can be in another translation unit and does not need to be included. Am I wrong with the way I am reading it or did I write something incorrectly? If I include the header, it works, as it should, even without the extern declaration.
Header files are usually not translation units but meant to be included by them. That's why header files usually do not "define" variables, since this would lead to multiple definition errors when the header file is included by different translation units (thereby re-defining the variable again and again).
That's where "extern" comes into place, since this is for just "declaring" a variable without "defining" it. "extern" means "will be defined in some other translation unit".
So the usual way is:
// Test.h
extern int externalint; // just declares externalint
// Test.cpp
int externalint = 10; // defines externalint
// main.cpp
#include "Test.h" // importing the declaration of "externalint" defined elsewhere
int main() {
std::cout << externalint << std::endl;
}
Header files are not typically translation units.
Put the definition in a Test.cpp file.
int externalInteger = 10;
Put your main function in Main.cpp file.
#include <iostream>
int main()
{
extern int externalInteger;
std::cout << externalInteger << std::endl;
std::cin.ignore();
}
Compile and link.
g++ -c Test.cpp
g++ -c Main.cpp
g++ Main.o Test.o
For MS, use cl.exe as the compiler instead of g++.
First ask yourself why would you use such a thing as extern. And then you will understand how to use it.
Imagine you would like a piece of code to be called in different programs.
Once from console application and once from an external program.
So you will write Test.cpp.
Now you can use it at console app using main() function and once you build it together with the external program you can use it there too.
Both will use the externalint value of 10 and as long as you update this Test library in both projects like through git. You would have the identical behaviour in both the console application and the external program.
Where is the Test.h you ask?
There you go:
The Test.cpp will be compiled separately from your Main.cpp but you would like to use the variables and functions from your Test.cpp. How does the compiler know what functions are there?
You will let him know.
You simply create an interface -> Test.h.
And then you will include it in your Main.cpp
#include "Test.h"
Example of interface:
//Test.h
int externalint = 10;
But, what if you have more .cpp files interested in this interface?
Then it will be duplicate and it will not compile. Because you cannot initialize the same variable twice.
Luckily you can declare it and announce that the initialization will be done in one of the .cpp files.
// Test.h
extern int externint;
// Test.cpp
int externint = 10;
I have a function that is the same across all my header files and main.cpp if I define it in main.cpp will they all be able to use it once they are included or will they have a compiler issue?
Still new to this whole header file business. Thanks in advance.
In the header file (myfunction.h), you need to have only declaration of the function:
int foo(int param);
In the main.cpp (or any other cpp file - better choice would be myfunction.cpp - just make sure definition is included in exactly one file!) file, you need to have definition of the function:
int foo(int param)
{
return 1;
}
In all other source (cpp) files where you're using function foo, just include myfunction.h and use function:
#include "myfunction.h"
void someotherfunction()
{
std::cout << foo(1) << std::endl;
}
Compiler only needs to see declaration of the function before it is used. Linker will connect definition of the function with the places you've used the function. If you forget to write definition in main.cpp file, you will not get compiler, but a linker error. It may be worth of mentioning that compiler is compiling each cpp file separately, and linker's job is to combine all compiler object files and to produce final output file. On most setups, linker will be called automatically after compiling, so you may not be familiar with it.
If you include entire function definition in the header file, that definition will be compiled in each translation unit where header file is included, and you will get multiple symbol definition linker error, or something similar - that's why you need to include only declaration of the function inside header file. However, there are exceptions for this - for example, you may declare your function inline - other answers explain this approach.
So, now myfunction.h contains the function declaration:
#ifndef MY_FUNCTION_H
#define MY_FUNCITON_H
// declaration
int myfunction();
#end if
myfunction.cpp contains the function definition:
int myfunction()
{
return 4;
}
Now, in file1.cpp and in file2.cpp you want to use this function, so you're including myfunction.h:
// file1.cpp
#include "myfunction.h"
// somewhere in the file
void foo()
{
std::cout << myfunction();
}
... and in the second file:
// file2.cpp
#include "myfunction.h"
// somewhere in the file
void bar()
{
/// ...
std::cout << myfunction();
}
Header files in C and C++ are a language artifact. They are the consequence of the fact, that C and C++ can be implemented as a single-pass compiler. In contrast, Pascal - for example - has a two-pass compiler, that skips over unknown entities during the first pass, and fills in the missing bits in a second pass. Consequently, in C and C++ every type, object, and method must be declared before it can be used. This is the main responsibility of header files.
Header files are expanded into any file that includes them. In other words: The preprocessor replaces the statement #include "foo.h" with the contents of the file "foo.h". With this being the case you need to be careful to not violate the single definition rule: An entity must not be defined more than once.
To meet both requirements you have two options: Declare and define the function in the header, using the inline keyword, or declaring it in the header only, and defining it in another compilation unit.
The following code illustrates both solutions:
// foo.h
inline void foo() {
// Method is implemented in this header file.
// It is marked 'inline' to prevent linker errors
// concerning multiply defined symbols.
...
}
Delaration in header only, implementation in another compilation unit:
// foo.h
extern void foo();
// foo.cpp (or another compilation unit)
void foo() {
...
}
Regardless of which solution you go with, you can use foo() from any compilation unit. If you want to use it from "main.cpp" the code would look something like this:
// main.cpp
#include "foo.h"
int main() {
foo();
}
So you have a function which is used in all your header files, why don't you make a utility.h which keeps track of these types of functions and inline the functions in the .h ?
Declare the function prototype in a custom header file:
int add(int a, int b);
let say header file name is myfunction.h and include it wherever you need the function.
now you can define a function on another.cpp or main.cpp
int add(int a, int b){
return a+b;
}
include your custom header file like this:
#include "myfunction.h"
remember your main.cpp and other cpp files and the new header file should be in the same path.
If you have two files:
main.cpp
#include "func.h"
int main(){
hello();
std::cout<<" world!\n";
return 0;
}
& func.h
#ifndef FUNC_H
#define FUNC_H
#include <iostream>
void hello(void){
std::cout<<"hello";
}
#endif
iostreams objects and functions e.t.c will work fine from within main.cpp.
This posts answers sum up #ifndef pretty well if you would like to know more.
I have read in places like here that you have to include .h files and not .cpp files, because otherwise then you get an error. So for example
main.cpp
#include <iostream>
#include "foop.h"
int main(int argc, char *argv[])
{
int x=42;
std::cout << x <<std::endl;
std::cout << foo(x) << std::endl;
return 0;
}
foop.h
#ifndef FOOP_H
#define FOOP_H
int foo(int a);
#endif
foop.cpp
int foo(int a){
return ++a;
}
works, but if I replace #include "foop.h" with #include "foop.cpp" I get an error (Using Dev C++ 4.9.9.2, Windows):
multiple definition of foo(int)
first defined here
Why is this?
What include does is copying all the contents from the file (which is the argument inside the <> or the "" ), so when the preproccesor finishes its work main.cpp will look like:
// iostream stuff
int foo(int a){
return ++a;
}
int main(int argc, char *argv[])
{
int x=42;
std::cout << x <<std::endl;
std::cout << foo(x) << std::endl;
return 0;
}
So foo will be defined in main.cpp, but a definition also exists in foop.cpp, so the compiler "gets confused" because of the function duplication.
There are many reasons to discourage including a .cpp file, but it isn't strictly disallowed. Your example should compile fine.
The problem is probably that you're compiling both main.cpp and foop.cpp, which means two copies of foop.cpp are being linked together. The linker is complaining about the duplication.
When you say #include "foop.cpp", it is as if you had copied the entire contents of foop.cpp and pasted it into main.cpp.
So when you compile main.cpp, the compiler emits a main.obj that contains the executable code for two functions: main and foo.
When you compile foop.cpp itself, the compiler emits a foop.obj that contains the executable code for function foo.
When you link them together, the compiler sees two definitions for function foo (one from main.obj and the other from foop.obj) and complains that you have multiple definitions.
This boils down to a difference between definitions and declarations.
You can declare functions and variables multiple times, in different translation units, or in the same translation unit. Once you declare a function or a variable, you can use it from that point on.
You can define a non-static function or a variable only once in all of your translation units. Defining non-static items more than once causes linker errors.
Headers generally contain declarations; cpp files contain definitions. When you include a file with definitions more than once, you get duplicates during linking.
In your situation one defintion comes from foo.cpp, and the other definition comes from main.cpp, which includes foo.cpp.
Note: if you change foo to be static, you would have no linking errors. Despite the lack of errors, this is not a good thing to do.
You should just include header file(s).
If you include header file, header file automatically finds .cpp file.
--> This process is done by LINKER.
Because of the One Definition Rule (probably1).
In C++, each non-inline object and function must have exactly one definition within the program. By #includeing the file in which foo(int) is defined (the CPP file), it is defined both in every file where foop.cpp is #included, and in foop.cpp itself (assuming foop.cpp is compiled).
You can make a function inline to override this behavior, but I'm not recommending that here. I have never seen a situation where it is necessary or even desirable to #include a CPP file.
There are situations where it is desireable to include a definition of something. This is specially true when you try to seperate the definition of a template from the declaration of it. In those cases, I name the file HPP rather than CPP to denote the difference.
1: "(probably)" I say probably here because the actual code you've posted should compile without errors, but given the compiler error it seems likely that the code you posted isn't exactly the same as the code you're compiling.
Because your program now contains two copies of the foo function, once inside foo.cpp and once inside main.cpp
Think of #include as an instruction to the compiler to copy/paste the contents of that file into your code, so you'll end up with a processed main.cpp that looks like this
#include <iostream> // actually you'll get the contents of the iostream header here, but I'm not going to include it!
int foo(int a){
return ++a;
}
int main(int argc, char *argv[])
{
int x=42;
std::cout << x <<std::endl;
std::cout << foo(x) << std::endl;
return 0;
}
and foo.cpp
int foo(int a){
return ++a;
}
hence the multiple definition error
So I found that if you are compiling from Visual Studios you just have to exclude the included .cpp file from the final build (that which you are extending from):
Visual Studios: .cpp file > right click > properties > configuration properties >
general > excluded from build > yes
I believe you can also exclude the file when compiling from the command line.
I want to clarify something: including header files is not neccessary to make the linker understand what you want. You can just declare it and it will be linked fine.
main.cpp:
#include <iostream.h>
//not including "foop.cpp"!
int foo(int a);
int main(){
std::cout << foo(4) << std::endln;
}
foop.cpp:
int foo(int a){
return a++;
}
I don't encourage doing like this, but know that headers are not some magic which you have to follow to make the code compile.
Using ".h" method is better
But if you really want to include the .cpp file then make foo(int) static in foo.cpp
My question does not link to a direct example, but is more of a question as a whole. When I was coding with C++, I found (after looking through some threads) that in order to use functions from different files that are in the same project, I would either need a header file. So, for example, if I have the main function in a file called "main.cpp" and I wanted to use a function, "prob1()" in another file called "problem1.cpp", I would need to use a header file.
What is confusing me is why I do not have to worry about this for programming in C? When I was programming in C, in order to use functions from different files, I could call the function directly.
Any help/explanation is appreciated. Thanks!
Your C compiler can implicitly declare the function, but you should be doing so yourself. If you turn up the warnings, you'll see something like:
file1.c: warning: implicit declaration of function ‘func_from_f2’
When file1.c is being compiled, this implicit declaration will be used to create an object file and then when linking you have to just hope that the function actually does exist and the declaration is correct so that the object files can be linked together successfully.
If not, the linker will give you an error somewhere along the lines of:
undefined reference to `func_from_f2'
You also don't necessarily need a header file, you can simply include the declaration/prototype of the function in your source file (the #include directive essentially does this for you). ie. the below will work fine without warnings:
file1.c
void func_from_f2(void);
int main(void)
{
func_from_f2();
return 0;
}
file2.c
#include <stdio.h>
void func_from_f2(void)
{
puts("hello");
}
However, it's usually best practice that you do use a header file:
file1.c
#include "file2.h"
int main(void)
{
func_from_f2();
return 0;
}
file2.h
#ifndef FILE2_H
#define FILE2_H
void func_from_f2(void);
#endif
file2.c
#include <stdio.h>
#include "file2.h"
void func_from_f2(void)
{
puts("hello");
}
In C, the compiler will guess the correct prototype if you haven't provided one. It very often guesses wrong, and then your program breaks.
Whether C or C++, it's always a good idea to put forward declarations in a header file that also gets #included into the implementation file, where the compiler can check for mismatch.