#1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Mar 2013
    Posts
    101
    Rep Power
    0

    Can I create a standard header file this way?


    I have a question.

    Say I wanted to create a header file. I just have this simple code, a print function.

    Code:
    void Print(char *word)
    {
             puts(word);
    }
    I save this as Print.h and it's located at my include file with the rest of header files like assert.h, stdio.h, etc.. Now, if I declare this, would it work or would I have to define a bunch of macros like the other header files.

    To simplify my question, can I make standard header files that are global the way local header files are made?
  2. #2
  3. Banned ;)
    Devshed Supreme Being (6500+ posts)

    Join Date
    Nov 2001
    Location
    Woodland Hills, Los Angeles County, California, USA
    Posts
    9,643
    Rep Power
    4248
    Yes you can do it, but you SHOULD NOT do it this way. You should not put code in header files (with some exceptions for C++, of course). Putting code in .h is just asking for trouble. Say you #include the .h file in more than one .c file, now your linker will complain that the function is declared twice.

    Therefore, you should only put public function prototypes, public struct definitions and macros in the .h file. The way you should do it is:

    print.h
    -------
    Code:
    #ifndef MYPRINT_H_2013_05_12
    #define MYPRINT_H_2013_05_12
    
    void Print(char *word); /* Only prototype here, with no code */
    
    #endif
    print.c
    -------
    Code:
    #include <stdio.h>
    #include "print.h"
    
    void Print(char *word)
    {
             puts(word);
    }
    Then, when you wish to use it in your own code, e.g.
    main.c
    -------
    Code:
    #include "print.h"
    
    int main(void) {
        Print("Hello World");
        return 0;
    }
    and in your project or Makefile, you tell it that the dependencies for your project are main.c and print.c. You can #include "print.h" in multiple .c files because the .h file only contains the function prototype, not actual code. Therefore, there is only one copy of the Print() function in the project, the code from print.c and you won't have linker errors.
    Up the Irons
    What Would Jimi Do? Smash amps. Burn guitar. Take the groupies home.
    "Death Before Dishonour, my Friends!!" - Bruce D ickinson, Iron Maiden Aug 20, 2005 @ OzzFest
    Down with Sharon Osbourne

    "I wouldn't hire a butcher to fix my car. I also wouldn't hire a marketing firm to build my website." - Nilpo
  4. #3
  5. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Mar 2013
    Posts
    101
    Rep Power
    0
    I see. Can you answer these two questions?

    1. I really didn't get to macros in my book yet (more at the end of the book)

    Code:
    #ifndef MYPRINT_H_2013_05_12
    #define MYPRINT_H_2013_05_12
    
    void Print(char *word); /* Only prototype here, with no code */
    
    #endif
    Not asking for a huge lecture here, but can you give me a brief summary why you used that name, "MYPRINT_H_2013_05_12"? I'll learn #define and #ifndef later but can that name be anything or does it have to be that.

    2. For your main function, why was your include declaration have quotes for "Print.h" and not <Print.h>. Wouldn't it be with the standard header files, so shouldn't it be treated like any other header file?
  6. #4
  7. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,242
    Rep Power
    2222
    You were asking one question, while Scorpions and I immediately saw the much bigger question. I hope you are beginning to understand why you must not put code in header files.

    Originally Posted by miz6565
    Not asking for a huge lecture here, but can you give me a brief summary why you used that name, "MYPRINT_H_2013_05_12"? I'll learn #define and #ifndef later but can that name be anything or does it have to be that.
    The fundamental reason for macros comes from assembly language, where by defining a macro, then everywhere you use it it will be inserted into the source code through what's called "macro expansion". That is how it's used in C, wherein the pre-processor modifies the source code by expanding the macros and performing the #include's.

    With macros (ie, the #define), you can define short in-line "functions". That is not what we are talking about here. Professionally, I've never used that feature in more than 20 years.

    With macros, you can "parameterize" constant values, such as the sizes of different types of arrays and upper and lower limits; read the limits.h header file for many such examples. We use this very often, though in C++ it's supposed to be replaced by const declarations. We are not talking about that feature here.

    With the #define statement, you can perform conditional compilation, which is very much what we are talking about here. We use this all the time, in part to be able to use the same source files in several different-though-related projects. You can #define or #undef a macro name, though you don't assign a value to it for macro expansion. Instead, you can place #ifdef or #ifndef statements in your code to mark which sections of code are to be included or excluded from the compile depending on whether that macro name had been #define'd or not (or #undef'd). There are also #else and #endif and the defined() macro with which you can build more complex conditional-compilation tests. The section in which your textbook covers this topic should use the term, "conditional compilation."

    Now to explain that example:
    Code:
    #ifndef MYPRINT_H_2013_05_12
    #define MYPRINT_H_2013_05_12
    
    void Print(char *word); /* Only prototype here, with no code */
    
    #endif
    The #include statement in the source file inserts the header file into the source file at that point. The #ifndef statement is conditional compilation. It says that the body of the header file between the #ifndef and the #endif will only be included if the macro name is not defined. If the same header file gets #include'd into the same source file -- this can very easily happen, since it is also a practice to place #include statements in header files -- then you only want to #include the body of the header file once. So the first time it's #include'd, the macro name is not #define'd, so the header file body gets #include'd. The very first thing the header file does is to #define the macro name. That way, the second, third, and n'th time the header file is #include'd, that macro name has been #define'd and hence the body of the header file will not be inserted into the source file.

    Remember, every source file is compiled separately and with no knowledge of what had happened in any other compilation. Any macro that was #define'd in another source file will not be #define'd in another, until a #define statement for that macro is encountered. This way, each header file will only be #include'd into any source file once and only once. I learned this technique as "guard defines", though I have also seen them called something like "guard includes".

    The reason for the name, MYPRINT_H_2013_05_12, is because that macro name must be unique. I would normally call it something like _MYPRINT_H_, but Scorpions chose to make it even more unique by including the date when it was written. When Microsoft's Visual Studio automatically creates a header file, it goes incredibly much further than Scorpions did in order to guarantee that the macro name is unique, as it must be in order to work.

    Originally Posted by miz6565
    2. For your main function, why was your include declaration have quotes for "Print.h" and not <Print.h>. Wouldn't it be with the standard header files, so shouldn't it be treated like any other header file?
    I see this as your actual original question, though it has been eclipsed by the far more important questions raised by your approach.

    I have not tried it yet, but I think that all you would need to do would be to place that header file in your compiler's INCLUDE directory. My reasoning is that the < > tells the pre-processor to look in that INCLUDE directory, whereas using "" tells it to look in the local directory.

    Hopefully, someone more knowledgeable in this will correct me if I'm wrong. But in the meantime, try it and see what happens. The compiler is, after all, the final arbiter in what you can and cannot do.
  8. #5
  9. Banned ;)
    Devshed Supreme Being (6500+ posts)

    Join Date
    Nov 2001
    Location
    Woodland Hills, Los Angeles County, California, USA
    Posts
    9,643
    Rep Power
    4248
    Originally Posted by dwise1_aol
    I have not tried it yet, but I think that all you would need to do would be to place that header file in your compiler's INCLUDE directory. My reasoning is that the < > tells the pre-processor to look in that INCLUDE directory, whereas using "" tells it to look in the local directory.

    Hopefully, someone more knowledgeable in this will correct me if I'm wrong. But in the meantime, try it and see what happens. The compiler is, after all, the final arbiter in what you can and cannot do.
    Actually sir, the standard doesn't specify the behavior of #include <> vs. "", so it is left to each compiler vendor as to how they choose to make it work. But most of them (at least every compiler I've used over the years) work like this:
    1. If the directive is #include <file.h>, then the compiler will first search the system directories, and then the local directories to look for file.h
    2. If the directive is #include "file.h", then the compiler will search the local directories first and then the system directories for file.h

    So the order of the search directories is different, but it does not matter if there is only one file.h, as both #include <file.h> and #include "file.h" will eventually find it.

    The only time it matters is if you name a .h file the same as that of a system file (for instance stdio.h), because the compiler will use the first matching header file that it finds.

    Comments on this post

    • dwise1_aol agrees : I've noticed in other people's code that it didn't seem to matter. I always use <> for system and "" for local, so I never tested it for myself.
    Last edited by Scorpions4ever; May 13th, 2013 at 05:35 AM.
    Up the Irons
    What Would Jimi Do? Smash amps. Burn guitar. Take the groupies home.
    "Death Before Dishonour, my Friends!!" - Bruce D ickinson, Iron Maiden Aug 20, 2005 @ OzzFest
    Down with Sharon Osbourne

    "I wouldn't hire a butcher to fix my car. I also wouldn't hire a marketing firm to build my website." - Nilpo
  10. #6
  11. Banned ;)
    Devshed Supreme Being (6500+ posts)

    Join Date
    Nov 2001
    Location
    Woodland Hills, Los Angeles County, California, USA
    Posts
    9,643
    Rep Power
    4248
    In addition to what dwise said above:
    Originally Posted by miz6565
    I see. Can you answer these two questions?

    1. I really didn't get to macros in my book yet (more at the end of the book)

    Code:
    #ifndef MYPRINT_H_2013_05_12
    #define MYPRINT_H_2013_05_12
    
    void Print(char *word); /* Only prototype here, with no code */
    
    #endif
    Not asking for a huge lecture here, but can you give me a brief summary why you used that name, "MYPRINT_H_2013_05_12"? I'll learn #define and #ifndef later but can that name be anything or does it have to be that.
    It can be any name as long as it is unique. I usually name it after the name of the header file and append the date when I first created the file to the end, to be sure that the name is unique.

    Originally Posted by miz6565
    2. For your main function, why was your include declaration have quotes for "Print.h" and not <Print.h>. Wouldn't it be with the standard header files, so shouldn't it be treated like any other header file?
    Just a programming convention I use with my code. I like to use #include <> with system header files and 3rd party library header files and #include "" with my own header files. That way I know who wrote what. Also see my reply above for the differences between <> and ""
    Up the Irons
    What Would Jimi Do? Smash amps. Burn guitar. Take the groupies home.
    "Death Before Dishonour, my Friends!!" - Bruce D ickinson, Iron Maiden Aug 20, 2005 @ OzzFest
    Down with Sharon Osbourne

    "I wouldn't hire a butcher to fix my car. I also wouldn't hire a marketing firm to build my website." - Nilpo
  12. #7
  13. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Mar 2013
    Posts
    101
    Rep Power
    0
    Yeah, hi.

    When I try to save the header file into the location it says I can't because I'm not allowed to and asks if I should save it to another location.

    Just asking, to make sure I'm doing this right, would you find this true to happen if you used Visual Studio 2010? LIke I said, when I try to save it won't let me. Says I'm not able to. Does this happen to other people or am I doing something wrong?
  14. #8
  15. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Mar 2013
    Posts
    101
    Rep Power
    0
    Wait, this seemed to work.

    #include "main directory\Visual Studio 2010\Projects\hello world1\hello world1\Print.h"

    Is that a weird way to include a header file? Just asking because it's not letting me save my header file(s) to the C header files. So should I just write my #include like above or keep on trying to save my files in my directory with the other header files?
  16. #9
  17. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,242
    Rep Power
    2222
    Originally Posted by miz6565
    When I try to save the header file into the location it says I can't because I'm not allowed to and asks if I should save it to another location.

    Just asking, to make sure I'm doing this right, would you find this true to happen if you used Visual Studio 2010? LIke I said, when I try to save it won't let me. Says I'm not able to. Does this happen to other people or am I doing something wrong?
    With Visual Studio 2008, I just saved a header file to the VC\include directory and it took it, no problem. Of course, I used Windows Explorer (or whatever it's called in Win7) instead of trying to do it within Visual Studio.

    One of the things you can do in Windows Explorer is to check the properties of that directory.

    PS
    Now that I'm at work with an XP box, I can copy-and-paste the path to the include directory:
    "C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include"
    Last edited by dwise1_aol; May 14th, 2013 at 11:18 AM.
  18. #10
  19. Contributed User
    Devshed Specialist (4000 - 4499 posts)

    Join Date
    Jun 2005
    Posts
    4,413
    Rep Power
    1871
    Originally Posted by miz6565
    Wait, this seemed to work.

    #include "main directory\Visual Studio 2010\Projects\hello world1\hello world1\Print.h"

    Is that a weird way to include a header file? Just asking because it's not letting me save my header file(s) to the C header files. So should I just write my #include like above or keep on trying to save my files in my directory with the other header files?
    No, this is totally the wrong thing to do.

    First off, if Print.h is part of the hello world1 project, then something short and simple like
    #include "Print.h"
    should work just fine for simple projects.

    If you've messed about with the default directory structure, then you might need something like
    #include "../inc/Print.h"

    Long absolute paths are always a mistake.



    You don't put your header files in the system include directory.
    1. You might trash something already there.
    2. Your stuff might get trashed on the next compiler upgrade / patch.

    Let's say you have a useful set of things you want to use across several projects.

    You would begin by creating a directory tree such as
    C:\projects\goodstuff\include
    C:\projects\goodstuff\inc
    C:\projects\goodstuff\lib
    C:\projects\goodstuff\source

    include is the public API to goodstuff, and would typically contain say goodstuff.h
    inc is a private directory of include files that you need to build goodstuff with (may be empty)
    lib is where all the library and dll files go (depending on whether you create static libs or DLLs)
    source is where your source code for goodstuff lives.

    Now, in your killerapp project, you would locate this dialog
    http://www.steptools.com/support/std...tings_vc6.html
    You might have to hunt around in your dialog if you're using a different version of studio, but the appropriate settings will be there.
    You need to find the following
    - Additional include directories (which you add C:\projects\goodstuff\include)
    - Additional library directories (add C:\projects\goodstuff\lib)
    - Additional libraries (add say goodstuff.lib)

    In your killerapp.cpp file, you would have
    #include <goodstuff.h>
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper
  20. #11
  21. Contributing User

    Join Date
    Aug 2003
    Location
    UK
    Posts
    5,117
    Rep Power
    1803
    Originally Posted by miz6565
    Wait, this seemed to work.

    #include "main directory\Visual Studio 2010\Projects\hello world1\hello world1\Print.h"

    Is that a weird way to include a header file? Just asking because it's not letting me save my header file(s) to the C header files. So should I just write my #include like above or keep on trying to save my files in my directory with the other header files?
    Yes it's weird, and makes your project non-portable to a different folder structure. And you really do not want to "pollute" the standard header folders with application specific headers. They do not belong there, and how would you then move your to another machine when you have to pick out all your own headers from thousands of others!?

    The preprocessor directive:
    Code:
    #include "header.h"
    causes the preprocessor to fist look in the same folder that the including file is in, it then looks in any include search paths provided on the compiler invocation command line (in an IDE these will be set some where in your project settings), then it will look in some standard header location(s).

    If you use
    Code:
    #include <header.h>
    it will do the same except for looking in the folder that the including file is in. This should generally be used for system files (i.e. those provided by the compiler and/or OS).

    You can as Salem suggested (or implied) create a separate folder for header files, however this means that you then have to add a header search path to your project, and it involves tedious folder navigation when opening your project files in an editor. Unless you are creating library where you might want the headers separate, I suggest that it is simpler to place headers and other source files in the same folder. For large projects you might want separate folders for packages or namespaces, but even then I keep the headers with their respective implementations.
  22. #12
  23. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Mar 2013
    Posts
    101
    Rep Power
    0
    Thanks guys. This REALLY helped.

    I haven't really "manipulated" any other files extensions so I will be dealing with .obj and .exe files for the first time. So if you guys may, I appreciate you helping me.

    Thanks again.

IMN logo majestic logo threadwatch logo seochat tools logo