Header files question

This is a discussion on Header files question within the C++ Programming forums, part of the General Programming Boards category; When you use the #ifndef directive with a header file, along with #define right after (for the same header file), ...

  1. #1
    Programming Ninja In-T...
    Join Date
    May 2009
    Posts
    827

    Question Header files question

    When you use the #ifndef directive with a header file, along with #define right after (for the same header file), is it necessary to still include the #include directive for the same header file, or are they mutually exclusive?
    Also, where should I use it? Do I just put #ifndef headerfilename at the beginning of my code (as you do with the #include directive), and #endif at the end of the whole program? Or am I supposed to use #endif right after I'm done using whatever functions the included header file contains?

  2. #2
    Captain Crash brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,237
    Quote Originally Posted by Programmer_P View Post
    When you use the #ifndef directive with a header file, along with #define right after (for the same header file), is it necessary to still include the #include directive for the same header file, or are they mutually exclusive?
    Also, where should I use it? Do I just put #ifndef headerfilename at the beginning of my code (as you do with the #include directive), and #endif at the end of the whole program? Or am I supposed to use #endif right after I'm done using whatever functions the included header file contains?
    You do none of the above. The #ifndef/#define/#endif header guard is done STRICTLY inside header files. Not .c or .cpp source modules. Unless you're writing your own headers, forget about the whole thing.
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  3. #3
    Programming Ninja In-T...
    Join Date
    May 2009
    Posts
    827

    Question

    Quote Originally Posted by brewbuck View Post
    You do none of the above. The #ifndef/#define/#endif header guard is done STRICTLY inside header files. Not .c or .cpp source modules. Unless you're writing your own headers, forget about the whole thing.
    According to this tutorial, it says the following:
    Avoiding Including Files Multiple Times (idempotency)
    Another common problem is that a header file is required in multiple other header files that are later included into a source code file, with the result often being that variables, structs, classes or functions appear to be defined multiple times (once for each time the header file is included). This can result in a lot of compile-time headaches. Fortunately, the preprocessor provides an easy technique for ensuring that any given file is included once and only once.

    By using the #ifndef directive, you can include a block of text only if a particular expression is undefined; then, within the header file, you can define the expression. This ensures that the code in the #ifndef is included only the first time the file is loaded.

    #ifndef _FILE_NAME_H_
    #define _FILE_NAME_H_

    /* code */

    #endif // #ifndef _FILE_NAME_H_

    Notice that it's not necessary to actually give a value to the expression _FILE_NAME_H_. It's sufficient to include the line "#define _FILE_NAME_H_" to make it "defined". (Note that there is an n in #ifndef--it stands for "if not defined").
    Do you mean to say, it is only for header (not source) files, that this is for?

  4. #4
    Captain Crash brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,237
    Quote Originally Posted by Programmer_P View Post
    According to this tutorial, it says the following:

    Do you mean to say, it is only for header (not source) files, that this is for?
    Yes. The advice to "avoid including header files multiple times" is somewhat misleading, because any decent header file will have inclusion guards, which prevent any problem if the file is included multiple times.

    In real world projects, it is often unavoidable that a header will be included multiple times, because you may have, for instance, a header A.h and a header B.h, both of which you need, and both of which themselves include a header C.h. That means C.h will be included twice. This is harmless, provided C.h has an include guard.

    As a USER of header files, you don't need to worry about it, unless you encounter a header without the correct include guards, in which case you'll need to do it yourself -- but the better option is to complain to the creator of the header file.
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  5. #5
    Programming Wraith GReaper's Avatar
    Join Date
    Apr 2009
    Location
    Greece
    Posts
    1,620
    Hey guys, i have a question. After #ifndef & #define etc, we strictly use this?
    DOG_H
    and not this?
    Gog_h

    Does it matter how you write it?

  6. #6
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    As long as you are consistent [=predictable] within your files, it's not particularly important. However, all macros are traditionally written in upper-case, to indicate that they are macros.

    There is no tecnical reason you can't use dog_h or Dog_H or DoG_h as your include guard name. However, if someone then uses dog_h as a name somewhere else, thinking that such a name is fine for "degeree of gradient - horizontally" [completely made up meaning!], then you will have mysterious/difficult error messages that can be very hard to resolve.

    It is much less likely that some programmer will name the function DOG_H, since that is generally preserved for macros. And if you define a macro called DOG_H (to something other than blank) and also include "dog.h", then the compiler will say "macro redefinition".

    Some people use really long and cryptic names as include guards, to avoid the chance of the macro name being used elsewhere, e.g. DOG_H_189374892_1211_19234791283_XXZVBF - you wouldn't accidentally get that in your code, I'd expect.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  7. #7
    Captain Crash brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,237
    Quote Originally Posted by matsp View Post
    Some people use really long and cryptic names as include guards, to avoid the chance of the macro name being used elsewhere, e.g. DOG_H_189374892_1211_19234791283_XXZVBF - you wouldn't accidentally get that in your code, I'd expect.
    It's also a potential problem when you are using more than one third party library. If two libraries both have a file config.h, and both of these files use an include guard "#ifndef CONFIG_H" then this will obviously cause a problem.

    Using a GUID (big random string) is one way to prevent this. Another is to be more specific when you choose the guard symbol. In my own projects, I use the format "<projectname>_<filename>_H__"

    So for a project called AudioGraph, header file AudioNode.h, the guard symbol would be:

    AUDIOGRAPH_AUDIONODE_H__

    The double trailing underscore? Yet another thing that increases the chances of a unique name. Of course, now that I've told you, you might start using it yourself

    EDIT: You could use a Java-style package naming convention, for something like this:

    COM_MYDOMAIN_MYPROJECT_MYHEADER_H__

    But in practice I've found the above mentioned technique is usually enough.
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  8. #8
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    21,457
    Quote Originally Posted by brewbuck
    The double trailing underscore? Yet another thing that increases the chances of a unique name. Of course, now that I've told you, you might start using it yourself
    That said, names that begin with an underscore followed by an uppercase letter, or that contain double underscores, are reserved to the implementation for any use. Plus, if everyone follows a convention of double trailing underscores, such a convention will not increase the chance of a unique name.
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  9. #9
    Captain Crash brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,237
    Quote Originally Posted by laserlight View Post
    That said, names that begin with an underscore followed by an uppercase letter, or that contain double underscores, are reserved to the implementation for any use. Plus, if everyone follows a convention of double trailing underscores, such a convention will not increase the chance of a unique name.
    Hmm. I did not know that double underscores were reserved ANYWHERE in a symbol name. I'll need to verify that.

    However, even if there is a symbol name clash, the project will most likely fail to compile. The chances of silently compiling an incorrect program are pretty low, it seems.
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Checking array for string
    By Ayreon in forum C Programming
    Replies: 87
    Last Post: 03-09-2009, 03:25 PM
  2. Header files in .h
    By swgh in forum C++ Programming
    Replies: 5
    Last Post: 05-29-2008, 08:58 AM
  3. quick question about header files
    By linucksrox in forum C++ Programming
    Replies: 11
    Last Post: 08-24-2005, 09:24 PM
  4. Request for comments
    By Prelude in forum A Brief History of Cprogramming.com
    Replies: 15
    Last Post: 01-02-2004, 09:33 AM
  5. Header files
    By borland_man in forum C++ Programming
    Replies: 14
    Last Post: 02-22-2002, 03:30 AM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21