This question already has answers here:
VS Code will not build c++ programs with multiple .ccp source files
(17 answers)
Closed 1 year ago.
I've watched several tutorials on C++ header files and did EXACTLY what they were showing, but I can't really understand why I can't use a function from other .cpp file.
Main.cpp
#include <iostream>
#include "Header.h"
int main() {
std::cout << sum(2, 2);
return 0;
}
Header.cpp
#include "Header.h"
int sum(int a, int b) {
return (a + b);
}
Header.h
#pragma once
int sum(int a, int b);
Your program is working as can be seen here.
To get your program working on your machine follow these steps(assuming you're using g++ and Ubuntu:
Step 1: Create a binary/executable using the command:
g++ main.cpp Header.cpp -o myexecutable
Step 2: Test/Run your executable created in the last step using the command:
./myexecutable
Alternate Solution: A shortcut
Now if you're wondering that you've to type the name of every source file to make the executable, then you can take a sigh of relief because there is a shortcut as given below:
Assuming you have many source files(.cpp files) in your current directory and you want to compile them all without writing the names of all of them, then you can use the command:
g++ ./*.cpp -o myexecutable
The above command will create a binary/executable named myexecutable .
By including files, the preprocessor simply makes the included file part of the file which includes the other file.
In C++, there is the one definition rule. If you include a definition multiple times in other files, you brake that rule. Simply that.
In general, the preprocessor nor the compiler has an idea what a '.h' or a '.cpp' file is, that is only a convention. But you must not have the same definition multiple times in your source files, independent if you link multiple objects or have the definition multiple times in one source file.
If you follow the convention, that you name your definition files with '.cpp', it makes no sense to include them in other files as this will end up in multiple definitions. Once in the object file generated from the '.cpp' file and once in the file which include the '*.cpp' file.
You can include the '.cpp' file once in another object file and use it, if you don't link the object file, which will be generated from that '.cpp' file. But is is a strongly advice to not do such strange things :-)
Related
For example:
I have a class called A. And there is:
A.hpp
A.cpp
main.cpp
for my project
By default, I only need to include A.hpp in the main so I can compile it, either using IDE such as Xcode or using:
g++ main.cpp A.cpp -o xxxxx
But the submission system only allows me to use:
g++ main.cpp -o xxxx
I tried to include A.cpp in the main, but the IDE says: main file cannot be included recursively when building a preamble
Is there any solution? I want to keep my hpp and cpp separately.
Can I include a cpp file
In theory, any file can be included.
But as a convention, you should never include cpp files.
But the submission system only allows me to use:
g++ main.cpp -o xxxx
If you cannot compile A.cpp then don't write such file at all. Write the definitions that you would have written in A.cpp into main.cpp instead. This achieves the same as including with a macro, but there won't be duplicate definitions in another cpp file.
You can #include any file you want. #include is automatic copy-paste. It looks in the file you tell it to include, and it reads whatever's in the file, and it pretends you wrote that in your original file. It doesn't care what's in the file, it just does that. You can include a .h file, a .hpp file, a .cpp file, a .txt file, a .py file, a .jpg file, or anything you want, as long as it's got valid C++ code in it.
Note that including a .cpp file is not the same as compiling it separately. And people expect that .cpp files are compiled separately, not included. To avoid confusing other programmers or the future version of yourself, you should rename the file to something else if you want to include it. You don't have to, but you should. If it's not a normal header file either (because you can't include it more than once), then you can make up some completely different extension, like .inc.
I am a C++ learner and I came across a concept of separating code into multiple files to speed up compiling process on bigger projects.
However what the book doesn't tell me and I have tried to find it in other books and on the web, but with no luck is how does linker (during compilation) knows what files to include.
When I make new file I connect its header to the main file with #include "newfile.h", however in this header I don't write where to find definitions of functions.
So how I imagine the process is that it starts in the main file and there it finds "connections" to other files. The question is how it finds those .cpp files that as far as I see don't need to be named the same as its header file.
Exmple:
Main file:
#include <iostream>
#include "krneki_H.h"
using namespace std;
int main()
{
krneki1();
krneki2();
krneki3();
}
And header file:
void krneki1();
void krneki2();
void krneki3();
And new .cpp file:
#include <iostream>
#include "krneki_H.h"
using namespace std;
void krneki1() {
cout<<"Krneki1"<<endl;}
void krneki2() {
cout<<"Krneki2"<<endl;}
void krneki3() {
cout<<"Krneki3"<<endl;}
Notice that there is no indication to use second cpp file. It just knows to use it. Does it search all .cpp files in the map?
Thank you for answer.
You compile both .cpp files using gcc -c or a similar command line, and then pass both of the .o files produced to the linker. The linker does not magically figure out that you want to compile another .cpp file.
For example
gcc -c main.cpp -o main.o # compile
gcc -c krneki_H.cpp -o krneki_H.o # compile
gcc main.o krneki_H.o -o main # link
Your IDE may take care of these details automatically, in which case it compiles all .cpp files you added to your project, then links all the .o files produced by the compilation step.
No. It doesn't just know to use it. In your example, if you compile with main.cpp and without that new cpp file, you'll get an "undefined reference" error.
What happens is that you're using a fancy IDE that automatically compiles all cpp files. It includes them all by default in your makefile.
I recommend that you try to design a makefile from scratch, and see for yourself how you'll get that "undefined reference" error if you don't include the cpp file that has the implementations of your functions.
I'm new to C++, and having difficulty understanding the steps of class object files getting created and compiled.
Let's say I create 3 files: 1. class header file 2. class cpp file (member function definitions present) 3. main cpp file
/*
When I run the main cpp file which includes the class header file (say as "#include class.h"), when does class cpp file get compiled, object file created, and linked?
The reason why I'm having difficulty is that from the compiler point of view, when it sees the main cpp file, there is only the header definition, no member function definition. However, even in the class header file, there is no class cpp file included. How would compiler know to run the class cpp file when it is not referred to in either class header file and the main cpp file?
*/
Let me clarify my question.
// Maybe I've said things I don't even understand lol.
So, basically I'm trying to run a main function in a say 'main.cpp' file. This 'main.cpp' file includes the 'class.h' header (include "class.h"). How would compiler execute the functions defined in header file when member function is not declared in 'class.h?' All my member function declaration is in 'class.cpp,' which is not included in 'class.h' or 'main.cpp.'
I suspect you're using an IDE, since you mention running cpp files - compilers don't know how to run anything.
Your IDE manages these dependencies for you.
When you press "Run", the IDE will decide which files in your project need compiling, and when the compilation is done it will link all the object files together.
If compilation and linking succeeded, the IDE then launches the executable program.
If you want a better understanding of the concepts, step away from your IDE and do all your compilation and linking on the command line for a while.
(It's not complicated, only tedious.)
You need to compile every .cpp file. Headers; .h files, are just for declarations, means that to let the compiler determine if you use the functions correctly. Each .cpp contains code and should be translated to machine code (.o files). After all these compilations, you need to link them to build the executable so that every function used is contained in the same file. The following commands can help you (using g++ compiler):
$ g++ -c myclass.cpp // produces the myclass.o file
$ g++ -c main.cpp // produces the main.o file
$ g++ -o myapp main.o myclass.o // produces the myapp executable
This is oversimplified for the sake of understanding.
First of all, I am a beginner programmer so, please give simple answers that are understandable.
I am suing Code::Blocks and I am trying to make a multiple file project in C++. I am using SDL2. My problem is that when I put all my codes and functions altogether, they run and when I seperate them, they don't. This is because the execution file requires object files to be built which it don't get. It don't get them because compiler don't form them. In other words, there are problems with linking. The compiler simply, said that there are not ".o" files. These files are in the project as "Link Files" and not "Compile Files". And when I make them "Compile Files" as well as "Link Files", they produces errors that various variables inside the file where I mentioned them, are not declared. But when I include that file in the file using the variables, it gets deeply nested.
Following are the two ways:
First way which is not working, with seperate files.
In main.cpp:
#include <SDL.h>
#include <other.h>
int var;
int linkVar;
int link1Var;
int link2Var;
#include "link.cpp"
#include "link1.cpp"
#include "link2.cpp"
int main( int argc, char* args[] )
{
linkFunc();
link1Func();
link2Func();
}
In link.cpp/ link1.cpp/ link2.cpp:
void linkFunc()/void link1Func()/void link2Func() //Just a reference
{
//Code associated with var, link1Var, link2Var and link3Var.
}
Second way which is working, with all functions in a single file.
First thing is that I don't want to learn makefile thing. If there is any other way to solve it then be it!
Code::Blocks makes object files for each file that it compiles as separate compilation units. It will compile and link together any files that are part of the project which it identifies as a source file.
First, remove your #includes of the cpp files. Then try the Project > Add files... menu option to add those other cpp files to the project.
First of all, you should not use #include on other cpp files, you can read about it here:
include cpp
Secondly when you are trying to compile a project composed of separate files you should use the g++ command like this: g++ main.cpp link.cpp link2.cpp etc'
you can read a basic explanation about it here: use the g++ command
To do exactly what you asked you should do:
# get rid of including any cpp files
# use forward declerations on any function belonging in other cpp files, before your main function like this:
void linkfunc();
void linkfunc2();
etc
.
.
.
int main()
{
}
# specify the direct path to your .h files like this:
#include <C:/MinGW/SDL2/SDL.h>
# use this command:
g++ -I C:/MinGW/SDL2/ main.cpp link.cpp link2.cpp link3.cpp
I have "Hello World" code that uses function fhi from another hi.cpp file that has it's header.
Correct my if my understanding is wrong according following:
I can do include cpp file like #include "c:\c\hi.cpp" instead of using header without any problems except that fact that it looks more readable in header file.
If I include header like sample in my main program hi.h, must hi.h include hi.cpp, or it is done automatically according the same file name hi. I'm wondering how compiler knows where is function fhi body.
Is it possible to have different names for header and cpp files?
Programm:
#include "stdafx.h"
#include "c:\c\hi.h"
int _tmain(int argc, _TCHAR* argv[])
{
fhi(1);
return 0;
}
hi.h
#include <cstdlib>
#include <iostream>
int var;
int fhi(int f);
hi.cpp
#include <cstdlib>
#include <iostream>
int fhi(int f)
{
return 0;
}
must hi.h include hi.cpp
No. hi.h contains only declarations, that can be other by other .cpp files.
I'm wondering how compiler knows where is function fhi body.
It doesn't. You need to compile all *.cpp files into the object files. In your case, you will have two object files: program.o and hi.o. The linker can now take these two object files, and spit out the executable. References to other functions(in this case the actual definition of fhi(..)) is resolved in this stage.
Also why are you using absolute paths in #includes? It will break when you move the "c" directory around.
What normally happens is that the build system compiles the .cpp files into object files, that then are used to build the main executable. The means to tell this to the build system vary greatly.
One important point is that your hi.cpp must include hi.h. You should also put an include guard in hi.h, to make it safe to be included more than once in a translation unit.
I can do include cpp file like #include "c:\c\hi.cpp" instead of using
header without any problems except that fact that it looks more
readable in header file.
yes, you can do so but it is not recommended, one of the problems is encapsulation; you are not hiding implementation details. readability as you mention is also a concern, a header is easier to read since it clearly shows what methods are public.
If I include header like sample in my main program hi.h, must hi.h
include hi.cpp, or it is done automatically according the same file
name hi. I'm wondering how compiler knows where is function fhi body.
the header needs to be explicitly included in hi.cpp and any .cpp file that use the class defined in the header.
Is it possible to have different names for header and cpp files?
yes but it is not recommended, it makes it more difficult to find things.
as a general rule: think about that other programmers may want to look in your code so you need to structure it so that it is easy to read and understand as well as making it easier for you 2 years down the road to remember where things are.
In Visual Studio all CPP files included in the project will be compiled to produce OBJ files. These OBJ files will be linked together to form the EXE or DLL.
Including files are similar to pasting the contents of the file at that location. The only difference is that this pasting is done by the pre-compiler during compilation.
Finding out where a function body resides is done by the either the compiler if the function is inline or by the linker when the final binary is created.
First, if the header file is in the same directory as the source file including it, you can use just
#include "hi.h"
In other words, you don't have to use a full path. (See e.g. the inclusion of "stdafx.h".)
Second, in your header file you don't need to include other header files, unless you need types from those. In your header file you don't have anything that needed from the header files you include.
Third, you should protect header files header files from being included more than once in the same source file, this can be done with a so called include guard, on in some compiler via a special directive called #pragma once.
Fourth, in your header file you define a global variable var. This variable will then be defined in every source file you include the header file in, which will lead to errors. You need to declare the variable as extern:
extern int var;
Then in one source file you define the variable like you do now.
Fifth, you should never include source files in header file (with some special exceptions that you don't have to think about yet). Instead you add all source files to the project (I assume you are in MS VisualStudio) and it they will all be built and linked together automatically.
Sixth, since you seem to be using VisualC++, then you are probably using something called precompiled headers. This is something the compiler uses to speed up compilation. However, for this to work you have to include "stdafx.h" in all source files. That include actually has to be the first non-comment line in each source file.