4

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.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055

4 Answers4

8

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
Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
  • +1 Ah..You beat me to it, The 2 stage process is exactly what OP needs to know & needs to be told.I am going to delete my incomplete answer. – Alok Save Jan 17 '12 at 11:03
  • 1
    Exactly but it should also be mentioned that dog.h is being included twice. The #include should be wrapped in: #ifndef ... #define blocks to stop that from happening. – vdbuilder Jan 17 '12 at 11:12
  • Thanks for your reply. I was using Code::Blocks, not using my own g++ command line. I've only ever used IDEs in Windows, so Linux(Ubuntu) is very different for me, and the nitty-gritty of it all is very interesting and not so automated. Can you recommend a good place where .o files are explained? I'm not even sure what they are :/ – ThomasuDesu Jan 17 '12 at 11:13
  • @vdbuilder: No, that is not correct. It is being included only once per translation unit; inclusion guards actually won't have any effect whatsoever because of this (they don't even exist by the time the linker gets a look in). (Though it's good practice anyway, for the day when it becomes included multiple times within the same TU.) – Lightness Races in Orbit Jan 17 '12 at 11:16
  • @ThomasuDesu: Then Code::Blocks knows which .cpp files are in your "project" and does the above automatically for you. I wouldn't worry about object files just yet. However, get yourself [a decent C++ book](http://jcatki.no-ip.org/fncpp/Resources) that explains the build process. – Lightness Races in Orbit Jan 17 '12 at 11:16
  • @Light Races in Orbit: Interesting. So basically a .o is a TU, which is a translation of C++ and English to machine code? And it is then linked together in the compiling stage to create an executable? Edit: Thanks for the reply, got to it before I did. I will invest in a good book I think. Had a Sam's Teach Yourself C++ In A Month or something, wasn't so great. Thank you very much for your time, at least now I know how much automation an IDE provided. – ThomasuDesu Jan 17 '12 at 11:19
  • @ThomasuDesu: Linked together in the linking stage. Yes, a .o is the compiled-to-machine-code representation of a single TU of C++. Typically, one or more of these is/are linked to create an executable. – Lightness Races in Orbit Jan 17 '12 at 11:28
0

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?

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
unwind
  • 391,730
  • 64
  • 469
  • 606
0

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.

Mr Lister
  • 45,515
  • 15
  • 108
  • 150
0

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.

Nick
  • 27,566
  • 12
  • 60
  • 72