Thread: Headers, header guards, pre-compiled headers and globals

  1. #1
    Registered User
    Join Date
    Nov 2013
    Posts
    107

    Headers, header guards, pre-compiled headers and globals

    This should be the first things you learn, however as my learning is pretty fragmented I still haven't really learned these things.

    I have Formatter.cpp and Formatter.h and Parser.cpp and Parser.h and stdafx.h in each at the top.

    I haven't done any classes just functions.

    Formatter.cpp has quite a few functions and no prototypes, all the prototypes are in Formatter.h

    Parser.cpp has quite a few functions and Formatter.h has just stdafx.h.

    All the includes are in stdafx.h including, Formatter.h and Parser.h.

    Now this all worked until I needed a global string say,

    Code:
    string sString = "stuff stuff1 stuff2";
    Now I initially had this in Formatter.cpp which has
    Code:
    int main(){}
    and passed this string to a function in Parser.cpp. This gives me a linking error, something like already referenced in Formatter.obj.

    So how do I understand all these things.

    By rule do you always put header guards in all .h files?

    And can you not just put all your prototype declarations in one .h files and then include all .h files in stdafx.h?

    And how about globals again why can't you just put everything in one header and have that header in stdafx.h?

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by jim_0
    Now this all worked until I needed a global string
    For a global variable, you should declare it as extern in a header file, then define it in exactly one source file.

    However, are you sure you need this string to be global? Is it a constant? If it is modifiable, then could you perhaps declare it say, in the main function and then pass it around (by reference)?

    Quote Originally Posted by jim_0
    By rule do you always put header guards in all .h files?
    Yes, I use header guards in all my header files.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by jim_0 View Post
    Parser.cpp has quite a few functions and Formatter.h has just stdafx.h.
    Header files should not include the pre-compiled header. That is what each source file should do as the first header it includes.

    Now I initially had this in Formatter.cpp which has
    Code:
    int main(){}
    and passed this string to a function in Parser.cpp. This gives me a linking error, something like already referenced in Formatter.obj.
    Sounds like you put globals in headers or included .cpp files. You should not do that.
    Declare globals in one source file (and exactly one) and declare it as extern in a header. Declaring something extern is just a way to tell the compiler the variable exists and not to create it.

    By rule do you always put header guards in all .h files?
    Yes! Though, I tend to favour #pragma once. Always use include guards or #pragma once.

    And can you not just put all your prototype declarations in one .h files and then include all .h files in stdafx.h?
    Putting all declarations in one header goes against organization.

    And how about globals again why can't you just put everything in one header and have that header in stdafx.h?
    Because that headers gets included in all source files, which means that all of a sudden you have multiple global variables with the same name which leads to a linker error.

    Generally, precompiled headers are good because they speed up compilation. However, beware that they can also slow down compilation. Since the precompiled header contains many headers, there is a lot of data to parse. So every time any of the headers that are included in the PCH are changed, the PCH needs to be recompiled, which in turn causes all source files to be recompiled. Very expensive.
    So beware. Only put headers that are unlikely to change inside the PCH (e.g. system headers).
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  4. #4
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by Elysia View Post
    Declare globals in one source file (and exactly one) and declare it as extern in a header.
    Just to be clear (I know you know this Elysia) the declaration in a source file is a definition (i.e. it actually creates the variable, corresponding to the extern declarations in header files).

    Quote Originally Posted by Elysia View Post
    Yes! Though, I tend to favour #pragma once. Always use include guards or #pragma once.
    On this point, I disagree. #pragma once is not guaranteed to meet the requirement (by definition, as pragmas are compiler specific hooks, and the standard specifies no pragmas) and an #include guard will always work (if care is taken to ensure the guarding macro name is unique in a project). I would always use #include guards, unless I have a particular reason not to (which is rare), and never use #pragma once.

    Some compilers (or, more accurately, preprocessors) have special handling of #include guards to speed up compilation but, even if that isn't so, #include guards are a technique that will work. #pragma once is a technique that will often (not always) work.

    Quote Originally Posted by Elysia View Post
    Generally, precompiled headers are good because they speed up compilation. However, beware that they can also slow down compilation. Since the precompiled header contains many headers, there is a lot of data to parse. So every time any of the headers that are included in the PCH are changed, the PCH needs to be recompiled, which in turn causes all source files to be recompiled. Very expensive.
    So beware. Only put headers that are unlikely to change inside the PCH (e.g. system headers).
    Personally, I turn off precompiled headers completely, unless the project is VERY small. Too many compilers that implement precompiled headers can still get confused (for example, if a header file gets changed, the precompiled header does not get rebuilt, so the affected source files are not recompiled at all). Tracking down bugs that result (where, for example, one source file is effectively compiled with a superseded header, and one is not, but the objects are linked together to form an executable) is hideously difficult.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  5. #5
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by grumpy View Post
    On this point, I disagree. #pragma once is not guaranteed to meet the requirement (by definition, as pragmas are compiler specific hooks, and the standard specifies no pragmas) and an #include guard will always work (if care is taken to ensure the guarding macro name is unique in a project). I would always use #include guards, unless I have a particular reason not to (which is rare), and never use #pragma once.

    Some compilers (or, more accurately, preprocessors) have special handling of #include guards to speed up compilation but, even if that isn't so, #include guards are a technique that will work. #pragma once is a technique that will often (not always) work.
    Oh, I didn't say you should prefer #pragma once over include guards. Include guards are superior, but are also incredibly annoying to have to type out for every header file make unique.
    #pragma once works with the popular compilers, so myself, I tend to use them since it's so much easier.

    Personally, I turn off precompiled headers completely, unless the project is VERY small. Too many compilers that implement precompiled headers can still get confused (for example, if a header file gets changed, the precompiled header does not get rebuilt, so the affected source files are not recompiled at all). Tracking down bugs that result (where, for example, one source file is effectively compiled with a superseded header, and one is not, but the objects are linked together to form an executable) is hideously difficult.
    You may have a point there, but usually compilers other than your popular PC compilers, tend to have quirks and other sources of frustration and bugs, so you're going to have to end up having to learn how to tame them anyway, so it's not like PCH not working properly might come as a surprise here... it's usually part of learning what the compiler can do and can't and how to fix it.
    Presumably you meant very big or something? Very small doesn't make any sense.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  6. #6
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by Elysia View Post
    Oh, I didn't say you should prefer #pragma once over include guards. Include guards are superior, but are also incredibly annoying to have to type out for every header file make unique.
    #pragma once works with the popular compilers, so myself, I tend to use them since it's so much easier.
    Okay. I must have read more than you intended in your previous post, when you said you favour pragma once.

    Quote Originally Posted by Elysia View Post
    You may have a point there, but usually compilers other than your popular PC compilers, tend to have quirks and other sources of frustration and bugs, so you're going to have to end up having to learn how to tame them anyway, so it's not like PCH not working properly might come as a surprise here... it's usually part of learning what the compiler can do and can't and how to fix it.
    Sure. Not using precompiled headers is often part of "taming the compiler".

    Quote Originally Posted by Elysia View Post
    Presumably you meant very big or something? Very small doesn't make any sense.
    Actually I did mean very small. Although my concept of "very small" (in rough terms, a development that takes 5 man years or less) exceeds what a lot of people would describe as large.

    Size, like beauty, is in the eye of the beholder.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  7. #7
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by grumpy View Post
    Sure. Not using precompiled headers is often part of "taming the compiler".
    Sure, if they cause more problems than they're worth, it's worth turning them off
    I just see finding out whether PCH are causing problems or not as part of the process of taming the compiler, not as a separate step.

    Quote Originally Posted by grumpy View Post
    Actually I did mean very small. Although my concept of "very small" (in rough terms, a development that takes 5 man years or less) exceeds what a lot of people would describe as large.

    Size, like beauty, is in the eye of the beholder.
    That sounds like a large project to me, though...
    Although PCH often pays off in projects which are very big in terms of source files or have very long compilation times rather than the time to market, so I cannot really tell how "big" or "small" such a project as you describe is...
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  8. #8
    Registered User
    Join Date
    May 2009
    Posts
    4,183
    I am trying to get the Code::Blocks project to use PCH header correctly.

    Some of the rules I found mainly by trial and error.

    1. Do NOT include a PCH header inside another regular header.
    2. Do include PCH header before any other includes in source files.
    3. Do NOT have compiler pragmas like implementation or interface before the PCH header include.

    Tim S.
    "...a computer is a stupid machine with the ability to do incredibly smart things, while computer programmers are smart people with the ability to do incredibly stupid things. They are,in short, a perfect match.." Bill Bryson

  9. #9
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by Elysia
    That sounds like a large project to me, though...
    The unit used is "man years", so once you start thinking in terms of a team of 10 to 20 people (team sizes that are achievable by maturing start-ups) it could feasibly be completed in half a year or less, upon which it does not sound so large any more.

    But yeah, "size, like beauty, is in the eye of the beholder". I certainly would not call such a development "very small".

    Quote Originally Posted by Elysia
    PCH often pays off in projects which are very big in terms of source files or have very long compilation times
    Which is why I advocate against the use of precompiled headers by students: they are unlikely to see the benefits, but still may have to deal with the problems.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  10. #10
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by laserlight View Post
    Which is why I advocate against the use of precompiled headers by students: they are unlikely to see the benefits, but still may have to deal with the problems.
    *shrug*
    Good learning experience. Plus, the only thing they have to do to experience long compilation times is to include Windows.h. Or boost.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Why do pre-compiled headers make my build take longer?
    By cpjust in forum C++ Programming
    Replies: 5
    Last Post: 02-22-2011, 12:44 PM
  2. Including headers in a header file
    By tjpanda in forum C++ Programming
    Replies: 3
    Last Post: 09-22-2008, 08:48 AM
  3. Pre-Compiled Headers
    By siavoshkc in forum C++ Programming
    Replies: 1
    Last Post: 08-06-2006, 05:55 PM
  4. including headers inside headers
    By kromozom in forum C++ Programming
    Replies: 5
    Last Post: 04-18-2005, 10:56 AM
  5. Header file include guards
    By foniks munkee in forum C Programming
    Replies: 4
    Last Post: 03-22-2002, 12:33 AM