quick question.
I am trying to get C++ nailed down, and today I spent hours with a double definition linker error("this has already been defined!") and I finally realised it's because I had the layout as such:
main.cpp
#include Dog.cpp
Dog.cpp
#include Dog.h
Dog.h
// (Dog class and prototype of test function)
And now that I've cleared that up by including the Dog.h instead of the Dog.cpp in the main.cpp.
By including the .h file, does the .cpp file with the identical prefix get compiled with the program?
I was astounded when the program ran with only the .h included and no references whatsoever to Dog.cpp. I spent ages Googling but no answers really helped me understand what was going on.
Edit: I forgot to add that I prototyped in the .h, and defined the function for the class in the .cpp and that's what gave me the "already defined" error.
By including the .h file, does the .cpp file with the identical prefix get compiled with the program? I was astounded when the program ran with only the .h included and no references whatsoever to Dog.cpp.
No.
Your program is built in phases.
For the compilation phase, only declarations are needed in each translation unit (roughly equivalent to a single .cpp file with #includes resolved). The reason that declarations even exist in the first place is as a kind of "promise" that the full function definition will be found later.
g++ -c Dog.cpp # produces `Dog.o`
g++ -c main.cpp # produces `main.o`
For the linking phase, symbols are resolved between translation units. You must be linking together the result of compiling Dog.cpp and of compiling main.cpp (perhaps your IDE is doing this for you?), and this link process finds all the correct function definitions between them to produce the final executable.
g++ Dog.o main.o -o program # produces executable `program`
(Either that, or you actually haven't got to the link phase yet, and merely have an object file (Dog.o); you can't execute it, partially because it doesn't have all the function definitions in.)
The two phases can be done at the same time, with the "shorthand":
g++ Dog.cpp main.cpp -o program # compiles, links and produces executable
No, the .cpp file does NOT automatically get compiled. You can either do that manually, create a makefile, or use an IDE that has both of them in the same project.
You don't specify how you are compiling it. If you are using an IDE and have a new .h and .cpp to the project automatically then it will all be compiled and linked automatically.
There are 2 stages to making an executable to run: compiling and linking. Compiling is where the code gets interpretted and translated into lower level code. Linking is where all of the functions that you used get resolved. This is where you got the duplicate function error.
Inclusion does not automatically cause compilation, no.
In fact, the actual compiler never sees the #include statement at all. It's removed by an earlier step (called the preprocessor).
I'm not sure how it could build if you never compiled the Dog.cpp file. Did you reference any objects with code defined in that file?
Related
I am using SWIG to wrap C++ code in Ruby.
I have eight classes defined in eight separate files in a specific location. I had two approaches to wrapping them in Ruby.
In the first approach, I put all the classes in one file, placed that file in the same directory as the SWIG interface file and everything is okay.
I am, however, requested to link to the original location of the files, and have my interface file in a different directory. When I compile, I compile all the files in their directory plus the wrapper code and there are no errors produced. However, I get undefined symbols.
A part of my compile shell script is:
g++ -std=c++11 -fPIC -c ../../dir1/dir2/Class.cpp
g++ -std=c++11 -fPIC -c mymodule_wrap.cxx -I/usr/include/ruby-1.9.1 -I/usr/include/ruby-1.9.1/x86_64-linux
I compile all the other seven files in the same way as the "File.cpp" one. No compilation errors.
Then, when I try the following
require 'mymodule'
c = Mymodule::Class.new
I get an undefined symbol for the Class' constructor (I demangled the undefined symbol using c++filt), which is declared and defined.
Is there something wrong in the way I compile? Or are there some problems when it comes to different locations of the header/source files and the SWIG interface file? Because this is in no way different from when I have all the classes in one file, except for the location.
EDIT:
If i move the definitions of the declared functions in the header files I get no undefined symbols. That means that it actually doesn't even reach the definitions in the cpp files. But why? When I had all classes unseparated I still kept the definitions in a cpp files and the declarations in a header file...
When creating the shared library, it didn't know where the object files of the source code were, therefore it never knew the definitions of whatever was declared in the header files.
For me, all the object files were created in the same folder as the interface file where I was compiling everything, and I added this:
g++ -shared Class.o mymodule_wrap.o -o mymodule.so
to my compile shell script. Before I was using the extconf makefile creating script, and I am not sure where it searched for the object files.
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.
I have a makefile that creates object files for two classes (and main) and one of those classes is just defined in a .h file. In my makefile I have a line that says
FileName.o: FileName.h
g++ -c FileName.h
but when I try to compile it says it can't find FileName.o
Do I have to create FileName.cpp in order to get this to compile?
You are using your class from FileName.h somewhere, aren't you? So at least one of your .cpp files should contain #include "FileName.h", and .h's code will be compiled with this .cpp and you needn't compile .h's code separately.
You don't normally attempt to compile a header (.h) file by itself. Including it into an otherwise empty .cpp file will let you compile it and produce a .o file, but it probably won't do much (if any) real good unless you've put things in the header that don't really belong in a header.
I guess I'm not linking something right?
I want to call ABC.cpp which needs XYZ.h and XYZ.cpp. All are in my current directory and I've tried #include <XYZ.h> as well as#include "XYZ.h".
Running $ g++ -I. -l. ABC.cpp at the Ubuntu 10 Terminal gives me:
`/tmp/ccCneYzI.o: In function `ABC(double, double, unsigned long)':
ABC.cpp:(.text+0x93): undefined reference to `GetOneGaussianByBoxMuller()'
collect2: ld returned 1 exit status`
Here's a summary of ABC.cpp:
#include "XYZ.h"
#include <iostream>
#include <cmath>
using namespace std;
double ABC(double X, double Y, unsigned long Z)
{
...stuff...
}
int main()
{
...cin, ABC(cin), return, cout...
}
Here's XYZ.h:
#ifndef XYZ_H
#define XYZ_H
double GetOneGaussianByBoxMuller();
#endif
Here's XYZ.cpp:
#include "XYZ.h"
#include <cstdlib>
#include <cmath>
// basic math functions are in std namespace but not in Visual C++ 6
//(comment's in code but I'm using GNU, not Visual C++)
#if !defined(_MSC_VER)
using namespace std;
#endif
double GetOneGaussianByBoxMuller()
{
...stuff...
}
I'm using GNU Compiler version g++ (Ubuntu 4.4.3-4ubuntu5) 4.4.3.
This is my first post; I hope I included everything that someone would need to know to help me. I have actually read the "Related Questions" and the Gough article listed in one of the responses, as well as searched around for the error message. However, I still can't figure out how it applies to my problem.
Thanks in advance!
When you run g++ -I. -l. ABC.cpp you are asking the compiler to create an executable out of ABC.cpp. But the code in this file replies on a function defined in XYZ.cpp, so the executable cannot be created due to that missing function.
You have two options (depending on what it is that you want to do). Either you give the compiler all of the source files at once so that it has all the definitions, e.g.
g++ -I. -l. ABC.cpp XYZ.cpp
or, you use the -c option compile to ABC.cpp to object code (.obj on Windows, .o in Linux) which can be linked later, e.g.
g++ -I. -l. -c ABC.cpp
Which will produce ABC.o which can be linked later with XYZ.o to produce an executable.
Edit: What is the difference between #including and linking?
Understanding this fully requires understanding exactly what happens when you compile a C++ program, which unfortunately even many people who consider themselves to be C++ programmers do not. At a high level, the compilation of a C++ program goes through three stages: preprocessing, compilation, and linking.
Preprocessing
Every line that starts with # is a preprocessor directive which is evaluated at the preprocessing stage. The #include directive is literally a copy-and-paste. If you write #include "XYZ.h", the preprocessor replaces that line with the entire contents of XYZ.h (including recursive evaluations of #include within XYZ.h).
The purpose of including is to make declarations visible. In order to use the function GetOneGaussianByBoxMuller, the compiler needs to know that GetOneGaussianByBoxMuller is a function, and to know what (if any) arguments it takes and what value it returns, the compiler will need to see a declaration for it. Declarations go in header files, and header files are included to make declarations visible to the compiler before the point of use.
Compiling
This is the part where the compiler runs and turns your source code into machine code. Note that machine code is not the same thing as executable code. An executable requires additional information about how to load the machine code and the data into memory, and how to bring in external dynamic libraries if necessary. That's not done here. This is just the part where your code goes from C++ to raw machine instructions.
Unlike Java, Python, and some other languages, C++ has no concept of a "module". Instead, C++ works in terms of translation units. In nearly all cases, a translation unit corresponds to a single (non-header) source code file, e.g. ABC.cpp or XYZ.cpp. Each translation unit is compiled independently (whether you run separate -c commands for them, or you give them to the compiler all at once).
When a source file is compiled, the preprocessor runs first, and does the #include copy-pasting as well as macros and other things that the preprocessor does. The result is one long stream of C++ code consisting of the contents of the source file and everything included by it (and everything included by what it included, etc...) This long stream of code is the translation unit.
When the translation unit is compiled, every function and every variable used must be declared. The compiler will not allow you to call a function for which there is no declaration or to use a global variable for which there is no declaration, because then it wouldn't know the types, parameters, return values, etc, involved and could not generate sensible code. That's why you need headers -- keep in mind that at this point the compiler is not even remotely aware of the existence of any other source files; it is only considering this stream of code produced by the processing of the #include directives.
In the machine code produced by the compiler, there are no such things as variable names or function names. Everything must become a memory address. Every global variable must be translated to a memory address where it is stored, and every function must have a memory address that the flow of execution jumps to when it is called. For things that are defined (i.e. for functions, implemented) in the translation unit, the compiler can assign an address. For things that are only declared (usually as a result of included headers) and not defined, the compiler does not at this point know what the memory address should be. These functions and global variables for which the compiler has only a declaration but not a definition/implementation, are called external symbols, and they are presumed to exist in a different translation unit. For now, their memory addresses are represented with placeholders.
For example, when compiling the translation unit corresponding to ABC.cpp, it has a definition (implementation) of ABC, so it can assign an address to the function ABC and wherever in that translation unit ABC is called, it can create a jump instruction to that address. On the other hand, although its declaration is visible, GetOneGaussianByBoxMuller is not implemented in that translation unit, so its address must be represented with a placeholder.
The result of compiling a translation unit is an object file (with the .o suffix on Linux).
Linking
One of the main jobs of the linker is to resolve external symbols. That is, the linker looks through a set of object files, sees what their external symbols are, and then tries to find out what memory address should be assigned to them, replacing the placeholder.
In your case the function GetOneGaussianByBoxMuller is defined in the translation unit corresponding to XYZ.cpp, so inside XYZ.o it has been assigned a specific memory address. In the translation unit corresponding to ABC.cpp, it was only declared, so inside ABC.o, it is only a placeholder (external symbol). The linker, if given both ABC.o and XYZ.o will see that ABC.o needs an address filled in for GetOneGaussianByBoxMuller, find that address in XYZ.o, and replace the placeholder in ABC.o with it. Addresses for external symbols can also be found in libraries.
If the linker fails to find an address for GetOneGaussianByBoxMuller (as it does in your example where it is only working on ABC.o, as a result of not having passed XYZ.cpp to the compiler), it will report an unresolved external symbol error, also described as an undefined reference.
Finally, once the compiler has resolved all external symbols, it combines all of the now-placeholder-free object code, adds in all the loading information that the operating system needs, and produces an executable. Tada!
Note that through all of this, the names of the files don't matter one bit. It's a convention that XYZ.h should contain declarations for things that are defined in XYZ.cpp, and it's good for maintainable code to organize things that way, but the compiler and linker don't care one bit whether that's true or not. The linker will look through all the object files it's given and only the object files it's given to try to resolve a symbol. It neither knows nor cares which header the declaration of the symbol was in, and it will not try to automatically pull in other object files or compile other source files in order to resolve a missing symbol.
... wow, that was long.
Try
g++ ABC.cpp XYZ.cpp
If you want to compile the seprately you need to build object files:
g++ -c ABC.cpp
g++ -c XYZ.cpp
g++ ABC.o XYZ.o
Wish I had read these when I was having these problems:
http://c.learncodethehardway.org/book/learn-c-the-hard-waych3.html
http://www.thegeekstuff.com/2010/08/make-utility/
I have text.cpp which includes header.h and header.cpp which includes header.h.
Will header.cpp be compiled as well? I'm following a guide here, and I am thoroughly confused.
Also, what is the correct terminology for what I am asking? I know I sound like a moron, and I apologize, but I'm ignorant.
Oh, int main() is in test.cpp.
Also, if header.cpp includes <iostream>, why can't I use iostream function calls in text.cpp if it is included? If I include <iostream> in text.cpp will it be included in the program twice (in other words, bloat it)?
You tell your compiler which C++ files to compile. #include has nothing to do with it.
For example, if you are using g++:
g++ text.cpp // Doesn't compile header.cpp
g++ text.cpp header.cpp // Compiles both
(or, alternatively you can compile one file at a time and then link them)
g++ text.cpp -o text.o
g++ header.cpp -o header.o
g++ text.o header.o -o your-program
If you use Visual Studio and you created a project, all C++ files you create will be automatically compiled.
If you are using neither, tell me the name of your compiler and I can tell you the exact syntax :)
Now, for your other question:
Also, if header.cpp includes
iostream, why can't I use iostream
function calls in text.cpp if it is
included? If I include iostream in
text.cpp will it be included in the
program twice (in other words, bloat
it)?
#include tells the compiler to simply "copy all the contents of the file you are including, and paste them where the #include line is". So, in theory, you could simply open iostream with notepad, select all, ctrl-c and ctrl-v it in your .cpp file and the end effect will be exactly the same =)
So yes it needs to be included for each .cpp file in which you wish to use it, and it won't "bloat" your program: it contains only class definitions, extern functions, etc.
Oh, and this goes without saying, but C++ is a very very vast and difficult programming language, you will have much better luck learning it through a book than a guide. If you don't want to spend any money, an okay free (downloadable) C++ book is Thinking in C++, Bruce Eckel. Otherwise if you want to buy one you can find a good list here.
header.cpp is only compiled if you compile it. It doesn't get automagically sucked up when you compile test.cpp. To produce a running program, you also have to link the resulting .o files in a single binary, as follows (oversimplified):
c++ -c test.cpp
c++ -c header.cpp
c++ -o test test.o header.o
You compile each source file separately, or together, then link the resulting object modules.
E.g. Visual C++ (Together)
cl text.cpp header.cpp /Fefoo
or separately,
cl /c text.cpp
cl /c header.cpp
link text.obj header.obj /out:foo.exe
To get a resultant EXE image, foo.exe.
Also, if header.cpp includes
, why can't I use iostream
function calls in text.cpp if it is
included? If I include iostream in
text.cpp will it be included in the
program twice (in other words, bloat
it)?
Since headers only contain declarations, there is no harm in including them many times. They will not bloat anything, since the compiler throws them away after doing type checking.
Though if you have type definitions in them, you need #include guards so that the types are not redefined.