Thread: precompiled header file

  1. #1
    Registered User
    Join Date
    May 2006
    Posts
    1,579

    precompiled header file

    Hello everyone,


    Here is my precompiled header settings,

    --------------------
    Create/Use PCH Through File stdafx.h
    PreCompiled Header File .\Debug/client.pch
    --------------------

    1.

    It means all the content before stdafx.h will be precompiled into client.pch? So that each time compiler "assumes" the content before stfafx.h will not be changed. Right?

    2.

    How will compiler solve this situation?

    Code:
    // in file foo.c
    #include "foo.h"
    #include "stdafx.h"
    
    // in file goo.c
    #include "goo.h"
    #include "stdafx.h"
    Compiler will pre-compile foo.h, goo.h and stdafx.h into one client.pch file? Or pre-compile foo.h + stdafx.h into one file, and pre-compile goo.h and stdafx.h into another file?


    thanks in advance,
    George

  2. #2
    Registered User
    Join Date
    Aug 2002
    Location
    Hermosa Beach, CA
    Posts
    446
    I am not 100% sure that I'm correct, but my understanding was that only stdafx.h (or whatever header file you call out in the Visual Studio settings) will be precompiled, and it must be the first header #included in the file.

    Here is more info:
    http://www.cygnus-software.com/paper...edheaders.html
    The crows maintain that a single crow could destroy the heavens. Doubtless this is so. But it proves nothing against the heavens, for the heavens signify simply: the impossibility of crows.

  3. #3
    Registered User
    Join Date
    May 2006
    Posts
    1,579
    Thanks IfYouSaySo,


    Great link, cool!!

    But I do not agree with you only the file "stdafx.h" is pre-compiled, I think all the files before and including the specified file parameter (e.g. stdafx.h) will be pre-compiled into one pch file.

    Do you have any comments?

    Here is the link from MSDN, and I quote related information from this link. :-)

    http://msdn2.microsoft.com/en-us/library/7zc28563.aspx

    --------------------
    If you use /Ycfilename, the compiler compiles all code up to and including the specified file for subsequent use with the /Yu option.
    --------------------

    Quote Originally Posted by IfYouSaySo View Post
    I am not 100% sure that I'm correct, but my understanding was that only stdafx.h (or whatever header file you call out in the Visual Studio settings) will be precompiled, and it must be the first header #included in the file.

    Here is more info:
    http://www.cygnus-software.com/paper...edheaders.html

    regards,
    George

  4. #4
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by George2 View Post
    But I do not agree with you only the file "stdafx.h" is pre-compiled, I think all the files before and including the specified file parameter (e.g. stdafx.h) will be pre-compiled into one pch file.

    Do you have any comments?
    No, that is incorrect. Only the contents of stdafx.h is precompiled. You must include stdafx.h as the first header in each source file or you will get compile errors.
    The compiler (or IDE?) can also typically detect when a header included in the PCH has changed, thus forcing a recompile of the header. Sometimes it doesn't work and requires a rebuild.
    The best bet is to include headers into the PCH that does not change.
    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.

  5. #5
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    You only use /Yc on a source file that contains nothing but the #include directive for the PCH source file. Every other source file uses /Yu.

    In a standard VS project, there's stdafx.h, stdafx.cpp, and various other files. The stdafx.cpp file looks like this:
    Code:
    #include "stdafx.h"
    and is compiled with a command line like this:
    cl.exe /Ycstdafx.h stdafx.cpp
    yielding stdafx.pch.
    All other sources are compiled with
    cl.exe /Yustdafx.h source.cpp


    OK, that much for the sane part. Now, the options really are quite insane. Consider that stdafx.h is empty and stdafx.cpp looks like this:
    Code:
    #include <iostream>
    #include <string>
    #include <vector>
    #include <windows.h>
    #include "stdafx.h"
    Then the compiler will create stdafx.pch containing the information from all these headers.

    While this is possible, it would be an extremely bad idea to rely on it. Let's say that source.cpp looks like this:
    Code:
    #include "stdafx.h"
    
    int APIENTRY WinMain(HINSTANCE inst, HINSTANCE, LPSTR cmdline, int showcmd)
    {
      std::vector<std::string> args;
      parse_cmdline(cmdline, args);
      // ...
    }
    Now compile with
    cl.exe /Yustdafx.h source.cpp
    This will work.

    Compile again with
    cl.exe source.cpp
    This will fail! Basically, you have different behaviour depending on whether you use PCH or not. That's totally unacceptable, which is why you should ignore this peculiarity of PCH support and simply do the sane thing: put the include directives in stdafx.h, where they belong.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  6. #6
    Registered User
    Join Date
    May 2006
    Posts
    1,579
    Thanks Elysia,


    Quote Originally Posted by Elysia View Post
    No, that is incorrect. Only the contents of stdafx.h is precompiled.
    No you are wrong, please read CornedBee's reply below. All the contents before stdafx.h and including stdafx.h will be pre-compiled.


    Hi CornedBee,


    Quote Originally Posted by CornedBee View Post
    Code:
    #include <iostream>
    #include <string>
    #include <vector>
    #include <windows.h>
    Compile again with
    cl.exe source.cpp
    I do not know why above compile will fail. If you do not use /Yu, no optimization which will use pre-compiled header file will be used. So, it should re-compile all the headers files into source.cpp. Why do you think there is an error?


    regards,
    George

  7. #7
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by George2 View Post
    No you are wrong, please read CornedBee's reply below. All the contents before stdafx.h and including stdafx.h will be pre-compiled.
    No. You are confused.
    Stdafx.cpp is a special file with special rules. Try to include any header before a precompiled header in any other file and you'll get a compile error.
    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
    Nov 2005
    Posts
    673
    It is simple. In any source file in a project that uses precompiled header, you must include the precompiled header "stdafx.h" in VC++. If you do not, then your program will not compile however hard you try.

  9. #9
    Registered User
    Join Date
    May 2006
    Posts
    1,579
    Hi Elysia,


    You are talking about stdafx.cpp? But we are talking about stdafx.h in your case. Can you read your post #4 again?

    This is what you said,

    --------------------
    No, that is incorrect. Only the contents of stdafx.h is precompiled. You must include stdafx.h as the first header in each source file or you will get compile errors.
    --------------------

    Quote Originally Posted by Elysia View Post
    No. You are confused.
    Stdafx.cpp is a special file with special rules. Try to include any header before a precompiled header in any other file and you'll get a compile error.

    Hi Raigne,


    I am totally confused. Why must I inlcude "stdafx.h" even if I do not need it? Suppose I have a project which needs to include foo.h in each source file, and foo.h is not prone to change, so I pre-compile foo.h into foo.pch and using /Yufoo.h to compile source files.

    Why do I need to add "stdafx.h" inside all source files in the scenario I described?

    Quote Originally Posted by Raigne View Post
    It is simple. In any source file in a project that uses precompiled header, you must include the precompiled header "stdafx.h" in VC++. If you do not, then your program will not compile however hard you try.

    regards,
    George

  10. #10
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by George2 View Post
    You are talking about stdafx.cpp? But we are talking about stdafx.h in your case. Can you read your post #4 again?
    Well, as I mentioned... in stdafx.cpp, this may be valid:

    #include <iostream>
    #include "stdafx.h"

    And in my_file.cpp, this is not valid:

    #include <iostream>
    #include "stdafx.h"

    You will get a compile error.
    At the same time, if my_file.cpp uses precompiled headers, the following won't work either:

    #include <iostream>

    (Note the missing "stdafx.h include.)
    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.

  11. #11
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by George2 View Post
    Hi Raigne,


    I am totally confused. Why must I inlcude "stdafx.h" even if I do not need it? Suppose I have a project which needs to include foo.h in each source file, and foo.h is not prone to change, so I pre-compile foo.h into foo.pch and using /Yufoo.h to compile source files.

    Why do I need to add "stdafx.h" inside all source files in the scenario I described?




    regards,
    George
    Because of the way that the compiler handles precompiled headers is that way - I presume what it actually does is load the precompiled header(s) into the internal tables first, then start parsing the rest of the code.

    It is an error to attempt to compile one module with precompiled headers and another module without. So don't do that.

    Edit: Note Elysia expands on this - it is possible, as long as you use the correct settings for each file, to have some files include the precompiled headers, and other files to NOT do that. However, we now come to a contentious issue of "what use is precompiled headers if they are not used in all [or at least most] source files?

    --
    Mats
    Last edited by matsp; 04-01-2008 at 08:38 AM.
    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.

  12. #12
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Speaking of which, you can tell Visual Studio that you don't want some source files to use precompiled headers via source-specific settings. It will compile fine if you do.
    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.

  13. #13
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Quote Originally Posted by George2 View Post
    I do not know why above compile will fail. If you do not use /Yu, no optimization which will use pre-compiled header file will be used. So, it should re-compile all the headers files into source.cpp. Why do you think there is an error?
    stdafx.h is empty. If PCH is disabled (no /Yu option), source.cpp will include the empty file and then attempt to use symbols from the headers included by stdafx.cpp. This will lead to compile errors.
    If PCH is enabled, the compiler sees the include of the empty stdafx.h as a directive to use stdafx.pch, which does include all those system headers.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  14. #14
    Registered User
    Join Date
    May 2006
    Posts
    1,579
    Hi Mats,


    stdafx.h is empty, do we have any practical benefits to always put it as the 1st include file into each source?

    Quote Originally Posted by matsp View Post
    Because of the way that the compiler handles precompiled headers is that way - I presume what it actually does is load the precompiled header(s) into the internal tables first, then start parsing the rest of the code.

    It is an error to attempt to compile one module with precompiled headers and another module without. So don't do that.

    Edit: Note Elysia expands on this - it is possible, as long as you use the correct settings for each file, to have some files include the precompiled headers, and other files to NOT do that. However, we now come to a contentious issue of "what use is precompiled headers if they are not used in all [or at least most] source files?

    --
    Mats

    Thanks CornedBee,


    I have checked you are correct. The content of stdafx.h is only one line, #pragma once, and the content of stdafx.cpp is only one line, #include "stdafx.h".

    My questions,

    1. Why do we need to include an empty include file stdafx.h? For what purpose?

    2. Do we always need to include it (stdafx.h)?

    3. I do not explicitly add stdafx.cpp into my project, do you mean it is added to each project implicitly?

    4. How is stdafx.pch generated? If it is generated from an empty stdafx.h, does it have any practical usage?

    Quote Originally Posted by CornedBee View Post
    stdafx.h is empty. If PCH is disabled (no /Yu option), source.cpp will include the empty file and then attempt to use symbols from the headers included by stdafx.cpp. This will lead to compile errors.
    If PCH is enabled, the compiler sees the include of the empty stdafx.h as a directive to use stdafx.pch, which does include all those system headers.

    regards,
    George

  15. #15
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by George2 View Post
    Hi Mats,


    stdafx.h is empty, do we have any practical benefits to always put it as the 1st include file into each source?
    Not that I can see - but stdafx.pch is created when you compile stdafx.cpp, so if stdafx.cpp contains other include files, those will be part of stdafx.pch as I understand it - but that also means that if you turn off PCH, then the project won't compile, which is bad.

    --
    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.

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. Need Help Fixing My C Program. Deals with File I/O
    By Matus in forum C Programming
    Replies: 7
    Last Post: 04-29-2008, 07:51 PM
  3. C++ std routines
    By siavoshkc in forum C++ Programming
    Replies: 33
    Last Post: 07-28-2006, 12:13 AM
  4. Unknown Memory Leak in Init() Function
    By CodeHacker in forum Windows Programming
    Replies: 3
    Last Post: 07-09-2004, 09:54 AM
  5. Replies: 6
    Last Post: 04-02-2002, 05:46 AM