Menu

Header File Problem

2008-09-18
2012-09-26
  • New Programmer

    New Programmer - 2008-09-18

    I am running Vista (which may well be the problem) and I am having so much trouble with header files not working or just ignoring lines of code in them. Here is my code:

    // myfile.h

    ifndef MYFILE_H_

    define MYFILE_H_

    include <iostream>

    using namespace std;

    int f1 (int x)
    {
    cout << x;
    return (x * x);
    }

    endif

    // main.cpp

    include <iostream>

    include "myfile.h"

    using namespace std;

    int main()
    {
    cout << f1(20);
    cout << endl;
    system("PAUSE");
    return 0;
    }

    My output is:

    400
    Press any key to continue...

    // end output

    So originally I didn't have the cout in my .h file, and then I added it and the iostream include and namespace. The problem is the output hasn't changed since adding all that. I would expect "20" to be displayed, but it isn't. Is it Vista? Am I missing something? Why don't I get an error.

    Please help this confused beginner, thanks.

     
    • cpns

      cpns - 2008-09-18

      You have made a number of mistakes. But the reason the code appears to be ignored is probably because the code was not recompiled. The "Compile Log" which you omitted ot post would show if that was the case.

      If you modify a header file, but Dev-C++ has not marked it as a dependency of the file including it, when you re-compile it will think the including file (main.cpp) to be up-to-date and will not re compile it. Dev-C++ has a 'fast' dependency generation mode in the tool options. It does not work, dont't use it.

      To force a complete rebuild use the "Rebuild All" menu option.

      Now all that said you are committing a number of fundamental errors that will cause you problems on more sophisticated applications. It is best to use good habits even when it may not technically matter:

      1) Header files should be declarative only and not contain executable code (with the exception of inlining).

      2) Declaring "using namespace std;" is dubious at best, but should certainly never bedone in a header file. You should never move anything from its namespace to teh global namespace in a header.

      To fix this and follow 'best practice', you need to use separate compilation (you'll need to create a 'project' in Dev-C++ to support that). The project might comprise the following files:


      // myfile.h

      ifndef MYFILE_H_

      define MYFILE_H_

      extern int f1 (int x) ;

      endif



      // myfile.cpp

      include <iostream>

      include <myfile.h>

      int f1 (int x)
      {
      std::cout << x;
      return (x * x);
      }



      // main.cpp

      include <iostream>

      include <cstdlib>

      include "myfile.h"

      using std::cout ;
      using std::endl ;

      int main()
      {
      cout << f1(20);
      cout << endl;
      system("PAUSE");
      return 0;
      }


      Note:

      1) myfile.h contains only a prototype declaration of f1()

      2) I did not bither with a using directibe in myifile.cpp because in this case using explicit scope resolution is trivial.

      3) myfile.cpp includes myfile.h. This allows teh compiler to check the declaration has teh same signature as teh definition.

      4) main.cpp includes myfile.h. The f1() declaration is all it knows at compilation, it is a 'promise' that the linker will later resolve.

      5) I used explicit using declaration only for the symbols used. The standard library is large and defines a number of symbols that you may never encounter, but if one of them happens to have the same identifier as something in your own code (and this is more common than you might think) the compiler error messages are likely to be very confusing to you.

      6) system() is declared in stdlib.h / cstdlib, so should be included. It may have worked merely by indirect inclusion through <iostream> but you cannot rely on such things, and it is not portable to other compilers.

      Clifford

       
      • Richard Kopcke

        Richard Kopcke - 2008-09-18

        include "myfile.h" versus

        include <myfile.h>

        Both appear in this program. Does it make a difference?

         
        • cpns

          cpns - 2008-09-18

          My typo. Use #include "myfile.h" throughout.

          It affects where the pre-processor looks for header files.

          Clifford

           
          • tugce özkaptan

            tugce özkaptan - 2008-10-01

            Hi!I have a problem about my header file while linking it its implementation file.
            My header file is;

            / boo.h /

            ifndef BOO_H

            define BOO_H

            define QUIET 1

            define MEDIUM 2

            define LOUD 3

            extern void say_boo(void);

            extern void change_boo_volume(int new_volume);

            endif

            and its implementation file is;
            / boo.c /

            include <stdio.h>

            include <stdlib.h>

            include <assert.h>

            include "boo.h"

            static void quiet_boo(void);
            static void medium_boo(void);
            static void loud_boo(void);

            static int volume_setting = MEDIUM;

            extern void say_boo(void)
            {
            switch( volume_setting ) {
            case QUIET:
            quiet_boo();
            break;
            case MEDIUM:
            medium_boo();
            break;
            case LOUD:
            loud_boo();
            break;
            default:
            fprintf(stderr, "\ndefault case was reached in %s, near line %d\n",
            FILE, LINE);
            abort();
            }
            }

            extern void change_boo_volume(int new_volume)
            {
            assert( new_volume >= QUIET && new_volume <= LOUD );

            volume_setting = new_volume;
            }

            static void quiet_boo(void)
            {
            printf("boo.\n");
            }

            static void medium_boo(void)
            {
            printf("Boo!\n");
            }

            static void loud_boo(void)
            {
            printf("BOO!!!\n");
            }

            and then Iwrote a text file for testing whether my program could run exactly or not.But I met one error on the compiler log part in the screen that is "cannot find -lobj" when I tried to compile my files.Actually this files I have sent them in this mail were given from one text-book.So, I do not think these are wrong.
            What is the meaning of this? And what should I do in this situation?

             
            • cpns

              cpns - 2008-10-01

              This has nothing to do with the subject of this thread, and it is not your thread to hijack in any case. Neither should you have e-mailed me directly! Start your own thread if my e-mail response was insufficient.

              Clifford

               
    • New Programmer

      New Programmer - 2008-09-19

      I am new to C++, but I think I understood most of what you said. Selecting "Rebuild All" really made a difference.

      Out of curiosity, why have a myfile.h and myfile.cpp? If the .h file is only used for declarations, couldn't you accomplish that in myfile.cpp? And why do you need #include "myfile.h" in both myfile.cpp and main.cpp?

      Thanks for the help.

       
    • cpns

      cpns - 2008-09-19

      > why have a myfile.h and myfile.cpp?

      When main.cpp and myfile.cpp are compiled, the compiler is run for each independently, one knows nothing about the other. myfile.h is 'advertising' the interface provided by myfile.cpp so that when main.cpp is compiled, it 'knows' how to use it.

      > If the .h file is only used for declarations, couldn't you accomplish that in myfile.cpp?

      No because it would be invisible to main.cpp - it is "separate compilation".

      > And why do you need #include "myfile.h" in both myfile.cpp and main.cpp?

      In main.cpp so the compiler knows how to use myfile.cpp's inteface, and in myfile.cpp so the compiler can check that the interface you are advertising is the interface you are providing. If you don't do this you would rely on the linker to spot the error, and in some cases it won't spot it.

      What you were doing before was essentially using the pre-processor for what the linker is intended and 'chaining' your code into a single compilation unit and getting teh compiler to do all the work. You get away with such things on trivial examples, but on a large project it would cause all sorts of problems. If for example you used separate compilation for a number of midules, and included your original myfile.h in more than one of them, the linker would see multiple definitions of f1(), when it must have only one. You can 'declare' as many times as you like, so long as each declaration is identical (which is why you use a header file), but you must have only one definition.

      I wrote this: https://sourceforge.net/forum/message.php?msg_id=2670009 a while back, you may find it useful.

      Clifford

       
    • New Programmer

      New Programmer - 2008-09-19

      Thanks for the advice.

       

Log in to post a comment.