in depth explaination...

Discussion in 'C++' started by josh, Nov 27, 2006.

  1. josh

    josh Guest

    hi all,
    If I have an interfacce file i.e. Time.h (where inside it I've #ifndef/
    #define / #endif directives) and then an implementation file i.e.
    Time.cpp in which I include Time.h and then a client file i.e. Test.cpp
    in which I include again Time.h I undtestand that the directives
    #ifndef/ #define / #endif make to insert one time only the file but
    I must anyway to include Test.h in Test.cpp for using the class I
    defined in Time.h else the compiler can't resolve the name......

    so I'm very confused..please help me
     
    josh, Nov 27, 2006
    #1
    1. Advertising

  2. josh wrote:
    > hi all,
    > If I have an interfacce file i.e. Time.h (where inside it I've #ifndef/
    > #define / #endif directives) and then an implementation file i.e.
    > Time.cpp in which I include Time.h and then a client file i.e. Test.cpp
    > in which I include again Time.h I undtestand that the directives
    > #ifndef/ #define / #endif make to insert one time only the file but
    > I must anyway to include Test.h in Test.cpp for using the class I
    > defined in Time.h else the compiler can't resolve the name......
    >
    > so I'm very confused..please help me
    >


    #ifndef/ #define / #endif is called an "include guard."

    It's purpose is NOT to insert the file one time only.

    It's purpose is to insert the file one time only WHILE compiling
    time.cpp, and to insert the file one time only WHILE compiling test.cpp.
    In other words, it prevents recursively including the same h file twice
    within one cpp file.

    Each cpp file is compiled separately and is compiled independently of
    all other cpp files.

    --
    Scott McPhillips [VC++ MVP]
     
    Scott McPhillips [MVP], Nov 27, 2006
    #2
    1. Advertising

  3. josh

    josh Guest

    On 27 Nov, 14:56, "Scott McPhillips [MVP]" <org-dot-mvps-at-scottmcp>
    wrote:
    > josh wrote:
    > > hi all,
    > > If I have an interfacce file i.e. Time.h (where inside it I've #ifndef/
    > > #define / #endif directives) and then an implementation file i.e.
    > > Time.cpp in which I include Time.h and then a client file i.e. Test.cpp
    > > in which I include again Time.h I undtestand that the directives
    > > #ifndef/ #define / #endif make to insert one time only the file but
    > > I must anyway to include Test.h in Test.cpp for using the class I
    > > defined in Time.h else the compiler can't resolve the name......

    >
    > > so I'm very confused..please help me#ifndef/ #define / #endif is called an "include guard."

    >
    > It's purpose is NOT to insert the file one time only.
    >
    > It's purpose is to insert the file one time only WHILE compiling
    > time.cpp, and to insert the file one time only WHILE compiling test.cpp.
    > In other words, it prevents recursively including the same h file twice
    > within one cpp file.
    >
    > Each cpp file is compiled separately and is compiled independently of
    > all other cpp files.


    so it prevents doing this:

    if I have a file named Date.h in which I have...
    #include "Time.h"
    ....

    and then in Test.cpp I make

    #include "Date.h"
    #include "Time.h"

    here Time.h is not included ... right?
     
    josh, Nov 27, 2006
    #3
  4. josh

    Guest

    On Nov 27, 3:30 pm, "josh" <> wrote:
    > On 27 Nov, 14:56, "Scott McPhillips [MVP]" <org-dot-mvps-at-scottmcp>
    > wrote:
    >
    >
    >
    > > josh wrote:
    > > > hi all,
    > > > If I have an interfacce file i.e. Time.h (where inside it I've #ifndef/
    > > > #define / #endif directives) and then an implementation file i.e.
    > > > Time.cpp in which I include Time.h and then a client file i.e. Test.cpp
    > > > in which I include again Time.h I undtestand that the directives
    > > > #ifndef/ #define / #endif make to insert one time only the file but
    > > > I must anyway to include Test.h in Test.cpp for using the class I
    > > > defined in Time.h else the compiler can't resolve the name......

    >
    > > > so I'm very confused..please help me#ifndef/ #define / #endif is called an "include guard."

    >
    > > It's purpose is NOT to insert the file one time only.

    >
    > > It's purpose is to insert the file one time only WHILE compiling
    > > time.cpp, and to insert the file one time only WHILE compiling test.cpp.
    > > In other words, it prevents recursively including the same h file twice
    > > within one cpp file.

    >
    > > Each cpp file is compiled separately and is compiled independently of
    > > all other cpp files.so it prevents doing this:

    >
    > if I have a file named Date.h in which I have...
    > #include "Time.h"
    > ...
    >
    > and then in Test.cpp I make
    >
    > #include "Date.h"
    > #include "Time.h"
    >
    > here Time.h is not included ... right?


    Only once, from the include in Date.h

    --
    Erik Wikström
     
    , Nov 27, 2006
    #4
  5. josh

    blangela Guest

    josh wrote:
    > On 27 Nov, 14:56, "Scott McPhillips [MVP]" <org-dot-mvps-at-scottmcp>
    > wrote:
    > > josh wrote:
    > > > hi all,
    > > > If I have an interfacce file i.e. Time.h (where inside it I've #ifndef/
    > > > #define / #endif directives) and then an implementation file i.e.
    > > > Time.cpp in which I include Time.h and then a client file i.e. Test.cpp
    > > > in which I include again Time.h I undtestand that the directives
    > > > #ifndef/ #define / #endif make to insert one time only the file but
    > > > I must anyway to include Test.h in Test.cpp for using the class I
    > > > defined in Time.h else the compiler can't resolve the name......

    > >
    > > > so I'm very confused..please help me#ifndef/ #define / #endif is called an "include guard."

    > >
    > > It's purpose is NOT to insert the file one time only.
    > >
    > > It's purpose is to insert the file one time only WHILE compiling
    > > time.cpp, and to insert the file one time only WHILE compiling test.cpp.
    > > In other words, it prevents recursively including the same h file twice
    > > within one cpp file.
    > >
    > > Each cpp file is compiled separately and is compiled independently of
    > > all other cpp files.

    >
    > so it prevents doing this:
    >
    > if I have a file named Date.h in which I have...
    > #include "Time.h"
    > ...
    >
    > and then in Test.cpp I make
    >
    > #include "Date.h"
    > #include "Time.h"
    >
    > here Time.h is not included ... right?


    Very good! You picked that up very fast. In fact, the example code you
    provided above is a much more "real life" example of where the #ifndef
    etc. is required. If it is used to prevent a recursive type situation,
    as described in an earlier post, my take on it is that the programmer
    has made a logic error. The situation you describe above is more of an
    oversight than a actual error in logic. At least, that is my take on
    it.

    Bob L.
     
    blangela, Nov 27, 2006
    #5
  6. josh

    josh Guest

    On 27 Nov, 21:34, "blangela" <> wrote:
    > josh wrote:
    > > On 27 Nov, 14:56, "Scott McPhillips [MVP]" <org-dot-mvps-at-scottmcp>
    > > wrote:
    > > > josh wrote:
    > > > > hi all,
    > > > > If I have an interfacce file i.e. Time.h (where inside it I've #ifndef/
    > > > > #define / #endif directives) and then an implementation file i.e.
    > > > > Time.cpp in which I include Time.h and then a client file i.e. Test.cpp
    > > > > in which I include again Time.h I undtestand that the directives
    > > > > #ifndef/ #define / #endif make to insert one time only the file but
    > > > > I must anyway to include Test.h in Test.cpp for using the class I
    > > > > defined in Time.h else the compiler can't resolve the name......

    >
    > > > > so I'm very confused..please help me#ifndef/ #define / #endif is called an "include guard."

    >
    > > > It's purpose is NOT to insert the file one time only.

    >
    > > > It's purpose is to insert the file one time only WHILE compiling
    > > > time.cpp, and to insert the file one time only WHILE compiling test.cpp.
    > > > In other words, it prevents recursively including the same h file twice
    > > > within one cpp file.

    >
    > > > Each cpp file is compiled separately and is compiled independently of
    > > > all other cpp files.

    >
    > > so it prevents doing this:

    >
    > > if I have a file named Date.h in which I have...
    > > #include "Time.h"
    > > ...

    >
    > > and then in Test.cpp I make

    >
    > > #include "Date.h"
    > > #include "Time.h"

    >
    > > here Time.h is not included ... right?Very good! You picked that up very fast. In fact, the example code you

    > provided above is a much more "real life" example of where the #ifndef
    > etc. is required. If it is used to prevent a recursive type situation,
    > as described in an earlier post, my take on it is that the programmer
    > has made a logic error. The situation you describe above is more of an
    > oversight than a actual error in logic. At least, that is my take on
    > it.
    >
    > Bob L.


    yes I agree with you and then I wonder me if I have the situation as
    described above
    there is no sense that the compiler includes more times the file
    (Time.h) with
    separate units (i.e. Test1.cpp Test2.cpp etc). Why the preprocessor and
    then the linker doesn't take all
    the files and then check if defined an include unit and so it includes
    **really** one
    time only???
     
    josh, Nov 28, 2006
    #6
  7. josh

    blangela Guest

    josh wrote:
    > On 27 Nov, 21:34, "blangela" <> wrote:
    > > josh wrote:
    > > > On 27 Nov, 14:56, "Scott McPhillips [MVP]" <org-dot-mvps-at-scottmcp>
    > > > wrote:
    > > > > josh wrote:
    > > > > > hi all,
    > > > > > If I have an interfacce file i.e. Time.h (where inside it I've #ifndef/
    > > > > > #define / #endif directives) and then an implementation file i.e.
    > > > > > Time.cpp in which I include Time.h and then a client file i.e. Test.cpp
    > > > > > in which I include again Time.h I undtestand that the directives
    > > > > > #ifndef/ #define / #endif make to insert one time only the file but
    > > > > > I must anyway to include Test.h in Test.cpp for using the class I
    > > > > > defined in Time.h else the compiler can't resolve the name......

    > >
    > > > > > so I'm very confused..please help me#ifndef/ #define / #endif is called an "include guard."

    > >
    > > > > It's purpose is NOT to insert the file one time only.

    > >
    > > > > It's purpose is to insert the file one time only WHILE compiling
    > > > > time.cpp, and to insert the file one time only WHILE compiling test.cpp.
    > > > > In other words, it prevents recursively including the same h file twice
    > > > > within one cpp file.

    > >
    > > > > Each cpp file is compiled separately and is compiled independently of
    > > > > all other cpp files.

    > >
    > > > so it prevents doing this:

    > >
    > > > if I have a file named Date.h in which I have...
    > > > #include "Time.h"
    > > > ...

    > >
    > > > and then in Test.cpp I make

    > >
    > > > #include "Date.h"
    > > > #include "Time.h"

    > >
    > > > here Time.h is not included ... right?Very good! You picked that up very fast. In fact, the example code you

    > > provided above is a much more "real life" example of where the #ifndef
    > > etc. is required. If it is used to prevent a recursive type situation,
    > > as described in an earlier post, my take on it is that the programmer
    > > has made a logic error. The situation you describe above is more of an
    > > oversight than a actual error in logic. At least, that is my take on
    > > it.
    > >
    > > Bob L.

    >
    > yes I agree with you and then I wonder me if I have the situation as
    > described above
    > there is no sense that the compiler includes more times the file
    > (Time.h) with
    > separate units (i.e. Test1.cpp Test2.cpp etc). Why the preprocessor and
    > then the linker doesn't take all
    > the files and then check if defined an include unit and so it includes
    > **really** one
    > time only???


    The linker simply links the separately compiled .cpp files. It is very
    important to realize that .h files are_NOT_ compiled as separate units.
    The C++ code in a .h file is only compiled if it is included in a .cpp
    file.

    Let us say that you have 3 .cpp files in your project. Each of these
    files are compiled separately. In fact it is very common to compile
    each .cpp file as required, and _not_ all at the same time.

    When you request to compile a .cpp file, the preprocessor executes
    first. One of the commands that it executes is the #include statement.
    The best way to think of the #include is as a copy and paste -- it
    copies the included file on top of (replacing IOW) the #include
    statement. If you have made a logic error of some type (as described
    in earlier posts) and do not have a safety system in place (like the
    #ifndef ...) then your compile will go off the rails because of an
    endless loop or because you compile the same .h file more than once.
    After the preprocessor is done, the actual compile of the (now
    modofied) .cpp file begins.

    Beginning C++ programmers have difficult time with this concept. For
    example if you leave off the ending ';' (semicolon) of your class
    definition in the class interface file (the .h file IOW), the error
    message (for some compilers) will appear near the beginning of the .cpp
    file that includes it. So then the student comes to me in a panic
    (typically in a lab exam) stating that they can see absolutely nothing
    wrong with their ctor, they have forgotten that the .h file included
    before the implementation of their ctor was compiled before the ctor,
    and that is where the error is originating from.

    I hope that clears up your question.

    Bob L.
     
    blangela, Nov 28, 2006
    #7
  8. josh

    BobR Guest

    blangela wrote in message ...
    >josh wrote:
    >>
    >> yes I agree with you and then I wonder me if I have the situation as
    >> described above
    >> there is no sense that the compiler includes more times the file
    >> (Time.h) with
    >> separate units (i.e. Test1.cpp Test2.cpp etc). Why the preprocessor and
    >> then the linker doesn't take all
    >> the files and then check if defined an include unit and so it includes
    >> **really** one
    >> time only???

    >
    >The linker simply links the separately compiled .cpp files. It is very
    >important to realize that .h files are_NOT_ compiled as separate units.
    > The C++ code in a .h file is only compiled if it is included in a .cpp
    >file.
    >Let us say that you have 3 .cpp files in your project. Each of these
    >files are compiled separately. In fact it is very common to compile
    >each .cpp file as required, and _not_ all at the same time.
    >
    >When you request to compile a .cpp file, the preprocessor executes
    >first. One of the commands that it executes is the #include statement.
    > The best way to think of the #include is as a copy and paste -- it
    >copies the included file on top of (replacing IOW) the #include
    >statement.


    To push that point:

    Most people think that they have to put the #include at the top of a (*.cpp,
    *.h) file. Fact is, they can be (almost) anywhere the included code is valid.

    Make two files:

    // --- Guts.h ---
    std::cout<<"Hello World, from Guts.h"<<std::endl;
    #define BLAHBLAH std::cout<<"Hello World2, from Guts.h"<<std::endl;
    // --- be sure that is all on one line! ---
    // --- Guts.h --- END

    // --- GutsMain.cpp ---
    #include <iostream>
    #include <ostream>

    int main(){
    #include "Guts.h"
    BLAHBLAH
    // looks weird, eh. (no semicolon at end)
    // note that very tricky nameing.<G>
    return 0;
    }
    // --- GutsMain.cpp --- END

    Compile 'GutsMain.cpp' and run it.

    Of course, using something like that in a real program would be insane [1].
    It's just to point out how '#include' and '#define' work.

    [1] - note that "Guts.h" depended on the std headers included in the
    "GutsMain.cpp". That should be avoided. Always include headers where needed,
    and let the 'include guards' do their job.

    --
    Bob R
    POVrookie
     
    BobR, Nov 28, 2006
    #8
  9. josh

    blangela Guest

    BobR wrote:
    > blangela wrote in message ...
    > >josh wrote:
    > >>
    > >> yes I agree with you and then I wonder me if I have the situation as
    > >> described above
    > >> there is no sense that the compiler includes more times the file
    > >> (Time.h) with
    > >> separate units (i.e. Test1.cpp Test2.cpp etc). Why the preprocessor and
    > >> then the linker doesn't take all
    > >> the files and then check if defined an include unit and so it includes
    > >> **really** one
    > >> time only???

    > >
    > >The linker simply links the separately compiled .cpp files. It is very
    > >important to realize that .h files are_NOT_ compiled as separate units.
    > > The C++ code in a .h file is only compiled if it is included in a .cpp
    > >file.
    > >Let us say that you have 3 .cpp files in your project. Each of these
    > >files are compiled separately. In fact it is very common to compile
    > >each .cpp file as required, and _not_ all at the same time.
    > >
    > >When you request to compile a .cpp file, the preprocessor executes
    > >first. One of the commands that it executes is the #include statement.
    > > The best way to think of the #include is as a copy and paste -- it
    > >copies the included file on top of (replacing IOW) the #include
    > >statement.

    >
    > To push that point:
    >
    > Most people think that they have to put the #include at the top of a (*.cpp,
    > *.h) file. Fact is, they can be (almost) anywhere the included code is valid.
    >
    > Make two files:
    >
    > // --- Guts.h ---
    > std::cout<<"Hello World, from Guts.h"<<std::endl;
    > #define BLAHBLAH std::cout<<"Hello World2, from Guts.h"<<std::endl;
    > // --- be sure that is all on one line! ---
    > // --- Guts.h --- END
    >
    > // --- GutsMain.cpp ---
    > #include <iostream>
    > #include <ostream>
    >
    > int main(){
    > #include "Guts.h"
    > BLAHBLAH
    > // looks weird, eh. (no semicolon at end)
    > // note that very tricky nameing.<G>
    > return 0;
    > }
    > // --- GutsMain.cpp --- END
    >
    > Compile 'GutsMain.cpp' and run it.
    >
    > Of course, using something like that in a real program would be insane [1].
    > It's just to point out how '#include' and '#define' work.
    >
    > [1] - note that "Guts.h" depended on the std headers included in the
    > "GutsMain.cpp". That should be avoided. Always include headers where needed,
    > and let the 'include guards' do their job.
    >
    > --
    > Bob R
    > POVrookie


    An example of puttng an #include statement at the end of a file is for
    a template class. Some programmers will have an #include statement at
    the end of the template class interface file, to effectively append the
    implementation of the template member functions of the class to the end
    of the class interface. This allows for still having separate files
    for both the template class interface and the template class
    implementation, as per usual.
     
    blangela, Nov 28, 2006
    #9
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. estafford
    Replies:
    3
    Views:
    394
    estafford
    Aug 22, 2003
  2. baumann@pan
    Replies:
    0
    Views:
    329
    baumann@pan
    May 19, 2005
  3. Drew
    Replies:
    4
    Views:
    332
  4. Replies:
    78
    Views:
    1,473
    David Thompson
    Sep 30, 2007
  5. Replies:
    5
    Views:
    832
    Roedy Green
    Apr 16, 2008
Loading...

Share This Page