Thread: building a large program

  1. #1
    Registered User
    Join Date
    Aug 2005
    Posts
    128

    building a large program

    Ok, I'm fine with creating a .cpp file with main() and then interacting with .h files using classes and namespaces and whatnot.

    My understanding is c++ compiles all files into one big file then into my .exe file. For that reason, include<> statements can be included multiple times if I'm not careful.

    Where I'm confused is using more than one .cpp file. For example, I have two programs, each with a main() in a .cpp file and each has one or two .h files. How do I link the main() .cpp file to the other cpp files? Do I make them into namespaces and include them via that method?

  2. #2
    Toaster Zach L.'s Avatar
    Join Date
    Aug 2001
    Posts
    2,686
    I don't understand how you would "include them via namespaces", but essentially the process is this. Say you have the following files and dependencies: file : dependencies

    foo.cc : foo.hh
    bar.cc : bar.hh foo.hh
    driver.cc : foo.hh bar.hh

    Now, via makefiles or projects, or whatever the setup your using uses:
    1. foo.cc which includes foo.hh will be compiled, creating an object file (say, foo.o)
    2. bar.cc which includes bar.hh and foo.hh (and needs the functionality in foo.cc through the foo.hh interface but does not include foo.cc) is compiled into bar.o -- now, there are "dangling" external links to foo.o
    3. driver.cc which includes bar.hh and foo.hh (and needs the functionality provided by the interface) is compiled into driver.o, again with "dangling" external references to foo.o and bar.o
    4. The linker comes along, and links driver.o, foo.o and bar.o into driver (the executable), and "connects" the functionality with the interfaces, thus resolving the external dependencies

    Now, if say, bar.o was never created (or an old, out of date version is used), the linker will not be able to find the function (class, whatever) externally refered to by driver, and hence will not be able to resolve the external dependency (hence the error: "Unresolved external error" which comes from your linker).

    So, no. Never include source files.*

    * There is an exception which is that templated functions must be defined in the same file they are declared in. I generally create a .tmpl file, and include it in the header file.
    The word rap as it applies to music is the result of a peculiar phonological rule which has stripped the word of its initial voiceless velar stop.

  3. #3
    Registered User
    Join Date
    Aug 2005
    Posts
    128
    Here's cpp file for main processing:
    let's say it's foo.cpp
    Code:
    //#include statements
    #include <foo.h>
    
    //create instance of vector which points to record struct.
    std::vector<nsSiteVector::record*> sitevector;
    
    int SiteScan();
    
    int main()
    {
    	//do a bunch of stuff related to foo.h
    	
                    //call BarScan 
                     BarScan();
    	return 0;
    }
    
    int BarScan()
    {
                   //mainBar is in bar.cpp with an included bar.h
    	mainBar();
    	return 0;
    }
    I thought the linker would combine all but then how would it know to include a cpp file unless I stated that in an include statement?

    Thansk for the linker information.

    My compiler isn't linking and I think it's because I'm not including the cpp file. I might be all wrong.

  4. #4
    Toaster Zach L.'s Avatar
    Join Date
    Aug 2001
    Posts
    2,686
    The compiler and linker are not the same program. The linker never even sees source files.

    It would help to know what compiler and IDE you are using to help resolve your problem. Also, the exact errors.

    That said, there are a few issues:
    1. SiteScan is declared but not defined. If you try to use it, you will get a "unresolved external". If it is defined in foo.h, then the compiler will see the declaration/definition followed by another declaration, and you will get a "multiple declaration" error.

    2. mainBar must be declared before it can be called, but it does not need to be defined (just as it is for a single file program). So, include "bar.h" in your file.

    3. Unless BarScan has a declaration in foo.h (or bar.h once you include it), you will run into the same problem as with mainBar.
    The word rap as it applies to music is the result of a peculiar phonological rule which has stripped the word of its initial voiceless velar stop.

  5. #5
    Registered User
    Join Date
    Aug 2005
    Posts
    128
    MSVC++ 6.0

    I'm looking into what you said. I think I'm starting to understand. if not, hit me with a frying pan.

  6. #6
    Registered User
    Join Date
    Aug 2005
    Posts
    128
    int SiteScan();
    should have been bar scan.

    Oh, so it's the .h files that make the bridge as far as the linker goes.

  7. #7
    Registered User
    Join Date
    Aug 2005
    Posts
    128
    I should note that one day, I'll start being a contributor here but so far, I'm find other peoples questions are out of my league or have already been ansered. Usually the former -

  8. #8
    Toaster Zach L.'s Avatar
    Join Date
    Aug 2001
    Posts
    2,686
    Frying pan on standby.

    Anyway, I would recommend upgrading from VC++6.0 to a newer compiler, e.g. .NET or GCC w/ Dev-C++ for standards compliance. However, that is irrelevant to the current issue. I've not use VC++ in a long time, but you should be able to create projects, and it will manage the dependencies for you so long as you include the right headers.

    Make sure everything you use has a declaration before it is used and a definition somewhere.

    A quick example:
    Code:
    // foo.hh
    #ifndef FOO_HH
    #define FOO_HH
    
    void foo( );
    
    #endif
    
    // foo.cc
    #include <iostream>
    #include "foo.hh"
    
    void foo( )
    {
       std::cout << "Inside foo( )" << std::endl;
    }
    
    //bar.hh
    #ifndef BAR_HH
    #define BAR_HH
    
    void bar( );
    
    #endif
    
    //bar.cc
    #include <iostream>
    #include "bar.hh"
    #include "foo.hh"
    
    void bar( )
    {
       std::cout << "Inside bar( )" << std::endl;
       foo( ); // It has been declared... linker will deal with the rest
    }
    
    //driver.cc
    #include "bar.hh"
    #include "foo.hh"
    
    int main( )
    {
       foo( );
       bar( );
    }
    The word rap as it applies to music is the result of a peculiar phonological rule which has stripped the word of its initial voiceless velar stop.

  9. #9
    Toaster Zach L.'s Avatar
    Join Date
    Aug 2001
    Posts
    2,686
    Quote Originally Posted by FoodDude
    int SiteScan();
    should have been bar scan.

    Oh, so it's the .h files that make the bridge as far as the linker goes.
    Essentially. Avoiding the details, the header says what the interface is, and this tells the linker what it needs to look for to connect function calls with functions.
    The word rap as it applies to music is the result of a peculiar phonological rule which has stripped the word of its initial voiceless velar stop.

  10. #10
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    No, header files do not "make the bridge as far as the linker goes". It is closer to say that the header files make the bridge as far as the compiler goes. The actual mechanisms depend on compiler and linker, but in broad terms are something like;

    1) Header files define the interface to functions as far as the C/C++ compiler is concerned. Header files are used in two places;

    a) They are #include'd by the source file that implements the body of the functions. The compiler uses the interface definition in the header file, and ensures that the implementation of the function matches the interface. It then places an entry into an object file that says to the linker "when something tries to call function X, resolve that call to this". A compiler error will occur if the implementation of the function does not match the interface from the header.

    b) Header files are also #include's by source files that need to call the functions. The compiler uses the interface definition and ensures that the ways the function are called match the interface. A compiler error will occur if the way the function is called does not match the interface specification in the header.

    2) The result of compiling multiple source files (each of which #include's a collection of headers) is a set of object files. For the linker to pull things together, it needs to be given a list of all the object files and also a set of libraries (which typically have the implementation of functions that are used by multiple programs). Each object file contains a set of function in compiled form (usually a machine dependent binary format). Each of those functions in compiled form typically does basic operations (eg manipulating data, moving it around) and may also call other functions. The linker builds a table of the links between those function calls, and basically ensures that --- when function A attempts to call function B --- that;
    a) control passes to the start of function B
    b) when function B finishes up, control passes back to the next operation in function B.
    The steps necessary to pass control between functions include things like saving values in machine registers and restoring them.

    If the linker encounters a situation where it can't resolve a call, it tends to complain bitterly because it cannot establish a link between caller and callee. However, if there are no unresolved calls, it essentially has a map of of how to put things together, and then is able to create an executable from all the compiled functions.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 8
    Last Post: 04-12-2007, 12:42 PM
  2. BOOKKEEPING PROGRAM, need help!
    By yabud in forum C Programming
    Replies: 3
    Last Post: 11-16-2006, 11:17 PM
  3. Can someome help me with a program please?
    By WinterInChicago in forum C++ Programming
    Replies: 3
    Last Post: 09-21-2006, 10:58 PM
  4. My program, anyhelp
    By @licomb in forum C Programming
    Replies: 14
    Last Post: 08-14-2001, 10:04 PM