28 Replies - 1001 Views - Last Post: 15 July 2012 - 10:31 PM
#16
Re: Please explain the scope resolution operator (::) & headers
Posted 15 July 2012 - 06:25 PM
#17
Re: Please explain the scope resolution operator (::) & headers
Posted 15 July 2012 - 06:30 PM
I should look into makefiles, I guess.
But I still don't see why you would go to the trouble of working with headers. I can code C++ just like Python/Java/PHP/etc by including .cpp files (generally with classes). I don't see how it's any different. Are these languages flawed because they work this way? Is their compile time at a disadvantage compared to C++ header users?
#18
Re: Please explain the scope resolution operator (::) & headers
Posted 15 July 2012 - 06:32 PM
AVReidy, on 16 July 2012 - 02:23 AM, said:
Are you confused as to how the compiler finds the definitions? it sounds to me that you are. Well, if so, during compilation you tell the compiler about all the source files. For example, imagine that you have two source files, "main.cpp" and "source.cpp". If these were to be compiled in the most basic way with the G++ compiler, you might do the following.
g++ main.cpp source.cpp
Obviously, if you have lots of source files and a more complex build processes, this becomes cumbersome. That's where makefiles are useful, since they allow you to make a build more automated.
This post has been edited by Aphex19: 15 July 2012 - 06:38 PM
#19
Re: Please explain the scope resolution operator (::) & headers
Posted 15 July 2012 - 06:35 PM
AVReidy, on 16 July 2012 - 03:30 AM, said:
You should look into makefiles, but you don't need them for this. If you just make sure that all the relevant object files are linked together, the code will work fine with or without makefiles.
Quote
Most of the languages you described are interpreted, so there's no such thing as compilation times there. In Java each class is compiled separately. So when you're compiling Java it works like c++ when you #include header, not cpp files. Also things like forward-declarations simply don't apply to Java.
#20
Re: Please explain the scope resolution operator (::) & headers
Posted 15 July 2012 - 06:38 PM
#include <iostream>
class Program {
public:
void go() {
std::cout << "Hey\n\n";
}
};
#include "Program.cpp"
int main() {
Program app;
app.go();
return 0;
}
Thanks.
EDIT: I guess including iostream multiple times later on would be an issue you brought up
This post has been edited by AVReidy: 15 July 2012 - 06:40 PM
#21
Re: Please explain the scope resolution operator (::) & headers
Posted 15 July 2012 - 06:42 PM
An object file is the result of compiling a cpp file. Multiple object files can be linked into one executable. If you do something like g++ bla.cpp the compiler will create an object file and then link it into an executable. If you do g++ -c bla.cpp, the compiler will create the object file (called bla.o) and not link it. If you then do g++ bla.o it will create an executable from that object file. If you want to compile multiple cpp files into one executable, you'd either do g++ file1.cpp file2.cpp file3.cpp (plus flags for warnings, debugging, optimization, -o etc. of course) or this:
g++ -c file1.cpp g++ -c file2.cpp g++ -c file3.cpp g++ file1.o file2.o file3.o -o myexecutable
The second one is the "proper" way because it's the way that allows you to only recompile those files that changed (and here's where makefiles become useful because you don't want to manually have to keep track of which files changed).
This post has been edited by sepp2k: 15 July 2012 - 06:48 PM
#22
Re: Please explain the scope resolution operator (::) & headers
Posted 15 July 2012 - 06:45 PM
In the code below, I #include <cstdlib> so that I can call std::rand(). If I crack open the header file cstdlib, it doesn't contain the implementation of the function. Yet, my program somehow manages to get a random number. Your assertion that one needs to include the implementation in the program by using #include has just fallen apart.
#include <cstdlib>
int main()
{
int x = std::rand() % 98;
return 0;
}
This post has been edited by Skydiver: 15 July 2012 - 06:46 PM
#23
Re: Please explain the scope resolution operator (::) & headers
Posted 15 July 2012 - 06:45 PM
Quote
No it is not normal practice to include a .cpp file. You normally add a cpp file to your IDE project, command line compile line, or make file.
Jim
#24
Re: Please explain the scope resolution operator (::) & headers
Posted 15 July 2012 - 06:54 PM
Program.h is just a regular header that declares a single function.
Program.cpp includes Program.h and defines the single function.
Main.cpp contains the int main() function.
How do I access the methods that were defined in Program.cpp? What does Main.cpp need to include?
#25
Re: Please explain the scope resolution operator (::) & headers
Posted 15 July 2012 - 06:55 PM
#26
Re: Please explain the scope resolution operator (::) & headers
Posted 15 July 2012 - 07:07 PM
How does the compiler know to look for the definition in a certain file? Is it only legal to define a declared method once? Does the compiler just search through everything for this definition until it finds it? Nothing at all points to "Program.cpp," so I assume it must.
Thanks.
#27
Re: Please explain the scope resolution operator (::) & headers
Posted 15 July 2012 - 07:12 PM
AVReidy, on 16 July 2012 - 04:07 AM, said:
The compiler doesn't need to see the definition of the function at all. It only needs to know the declaration. The linker will find the definition by simply going through all the linked object files and picking the function definition with the given name.
Quote
Yes.
Quote
The linker does, yes.
#28
Re: Please explain the scope resolution operator (::) & headers
Posted 15 July 2012 - 07:13 PM
#29
Re: Please explain the scope resolution operator (::) & headers
Posted 15 July 2012 - 10:31 PM
Lets start with a simple program and compile it at the command line:
HelloWorld.cpp
#include <iostream>
using namespace std;
int main() {
cout << "Hello World!" << endl;
return 0;
}
We run this past our compiler and it creates an object file. This is what compilers do, they take source code and create object code. Object code is "nearly completed" machine code + a bunch of meta-data about what symbols were what (i.e. which code goes with which block of machine code, what variables are needed etc.. So the Compiler creates say HelloWorld.obj
So I bet you were thinking that the compiler produced you final executable - but nope. Not the compiler's job. The compiler just produces an intermediate format called object code.
THEN the compiler hands that object code to a LINKER.
The reason the compiler does not do this step itself is generally "separation of concerns" but if you spend some time in assembly language you begin to appreciate the problem the compiler has: It does not know ahead of time the expected memory addresses of functions/variables etc. because it has not COMPILED the code yet and does not know the size of much of anything. So the compiler is really crippled when it comes to calculating addresses and optimizing layout etc.
So the LINKER take object files and library files (a library file contains a bunch of object files) and some templates for how a particular operating system likes its executables/libraries to look and glues them all together.
The object files and libraries actually are very handy! The linker can take any number of objects and libraries from different sources done at different times and stitch them together into executables.
This means that you don't need to compile all your code into one monolithic file, you can break it up and compile it in parts. You only need to "recompile" those files that have changed. When you are working on a project with 100's of files this can be a life saver since compiling the whole project can take hours.
So header files "enable" libraries and object files. They give the compiler the information needed to use objects stored in object files (functions/classes/variables/structures etc.).
When you #include <iostream> - you are telling the compiler all about std::cout and std::endl so that the compiler knows how to use them to do:
cout << "Hello World!" << endl;
if you had not done the include the compiler would not know how to use cout and endl.
------
So armed with this basic knowledge of compilers/linkers -- why should you never #include a .cpp file? The compiler will probably not care one little bit.
BUT THE LINKER will. we have the following.
Main.cpp -- includes myUsefullFunction.cpp which contains the function useful().
MySupport.cpp -- also includes myUsefullFunction.cpp.
The compiler compiles Main.cpp into Main.obj and MySupport.cpp into MySupport.obj...
The Linker opens these two up and find code for the function useful() TWICE (once in each object file). So now whenever you used useful() you *COULD* be talking about the one in main.obj or the one in mysupport.obj.
So to avoid this: break out the declaration of useful() into myUsefullfunction.h and compile the three files:
myUsefullfunction.cpp becomes myusefullfunction.obj
main.cpp -- #includes myusefulfuntion.h, compiles to main.obj
MySupport.cpp -- #includes myusefulfunction.h compiles to mysupport.obj
The linker combines the three object files and no longer finds a conflict. Since you probably also #included some standard library headers the compiler will ask the linker to also grab some object code from libraries and so long as everything is in order the linker will generate your executable for you!
|
|

New Topic/Question
Reply




MultiQuote




|