Precompiled header usage

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Andrew Ward

    #1

    Precompiled header usage

    Hi All,
    I was wondering if it is possible to use precompiled headers without having
    to include a <stdafx.h> or whatever in every source file.
    My problem is that I have a project that makes heavy usage of a large third
    party library which means after pre-processing each translation unit is
    around 1meg in size. There are reasons though why I cannot use the standard
    approach to precompiled headers.

    What I would like to do is somthing like this:
    1) create a header that includes all headers from third party library
    2) compile this into a .pch file
    3) have VS use this .pch file while compiling any source file it encounters

    Is this possible?

    Andy


  • Tanveer Gani [MSFT]

    #2
    Re: Precompiled header usage


    --------------------[color=blue]
    >From: "Andrew Ward" <anwar@ihug.co. nz>
    >References: <ury7e20dDHA.18 32@TK2MSFTNGP09 .phx.gbl>[/color]
    <uw6G2F1dDHA.10 08@TK2MSFTNGP12 .phx.gbl>[color=blue]
    >Subject: Re: Precompiled header usage
    >Date: Wed, 10 Sep 2003 17:26:22 +1200
    >Lines: 65
    >X-Priority: 3
    >X-MSMail-Priority: Normal
    >X-Newsreader: Microsoft Outlook Express 6.00.2800.1106
    >X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2800.1106
    >Message-ID: <ea9qYw1dDHA.19 32@TK2MSFTNGP10 .phx.gbl>
    >Newsgroups: microsoft.publi c.dotnet.langua ges.vc
    >NNTP-Posting-Host: 210-54-80-239.dialup.xtra .co.nz 210.54.80.239
    >Path: cpmsftngxa06.ph x.gbl!TK2MSFTNG P08.phx.gbl!TK2 MSFTNGP10.phx.g bl
    >Xref: cpmsftngxa06.ph x.gbl microsoft.publi c.dotnet.langua ges.vc:28151
    >X-Tomcat-NG: microsoft.publi c.dotnet.langua ges.vc
    >
    >Hi Brandon,
    >The problem I am facing is that I cannot add #include "all.h" or whatever[/color]
    to[color=blue]
    >each source file in the project. About half of the source that is compiled
    >for the project is c++ generated from XML specifications, this source is[/color]
    all[color=blue]
    >generated automatically in the build process.
    >
    >An approach like the following would be great for my type of build
    >environment:
    >
    >Each time the compiler encounters an #include <xyz.h> directive it checks a
    >cache to see if it has a precompiled version of the header 'xyz.pch' that[/color]
    is[color=blue]
    >up to date, if one is found then it is used, otherwise a new precompiled
    >header is created 'xyz.pch' and put in the cache.
    >
    >It seems to me that this approach would be more efficient as well, because
    >each file being compiled would only include the precompiled data that it
    >needs, instead of the norm of loading a huge precompiled header for every
    >source file, whether the file needs all the data or not.
    >
    >Is anything of this sort possible?
    >
    >
    >"Brandon Bray [MSFT]" <branbray@onlin e.microsoft.com > wrote in message
    >news:uw6G2F1dD HA.1008@TK2MSFT NGP12.phx.gbl.. .[color=green]
    >> Andrew Ward wrote:[color=darkred]
    >> > Hi All,
    >> > I was wondering if it is possible to use precompiled headers without
    >> > having to include a <stdafx.h> or whatever in every source file.
    >> > My problem is that I have a project that makes heavy usage of a large
    >> > third party library which means after pre-processing each translation
    >> > unit is around 1meg in size. There are reasons though why I cannot use
    >> > the standard approach to precompiled headers.
    >> >
    >> > What I would like to do is somthing like this:
    >> > 1) create a header that includes all headers from third party library
    >> > 2) compile this into a .pch file
    >> > 3) have VS use this .pch file while compiling any source file it
    >> > encounters
    >> >
    >> > Is this possible?[/color]
    >>
    >> Hi Andy,
    >> What you'd like to do is very easy. To create a precompiled header,[/color]
    >simply[color=green]
    >> tell the compiler which header that should be. Use the /Yc command-line
    >> switch to do that. Then when you want to use that precompiled header, use
    >> the /Yu switch.
    >>
    >> The precompiled header needs to be the first #include in the file.
    >>
    >> The only reason that you would need to use stdafx.h for that is because
    >> Visual Studio sets up projects to do this by default. You can of course
    >> change that. Go to your project properties to change which file the[/color]
    >project[color=green]
    >> uses.
    >>
    >> I hope that makes sense. Cheerio!
    >>
    >> --
    >> Brandon Bray Visual C++ Compiler
    >> This posting is provided AS IS with no warranties, and confers no rights.
    >>
    >>[/color]
    >
    >
    >[/color]

    Andy,

    You seem to have misunderstood the VC++ PCH mechanism. The PCH is not a
    more compact form of the header. It's really a dump of the compiler's
    symbol table at the #include point in a source file. When compiling a file
    with the same #include, the compiler can be made to load the PCH (really
    the symbol table) the assumption being that the internal state is now the
    same as if the #include had been processed at that point.

    You can make the compiler use a different PCH for each compiland, but the
    obvious advantage is when several compilands share a certain set of files.
    Then a PCH gets built once and re-used multiple times in a build. Building
    a PCH per file will save you time only if you're building the same file
    over and over, but PCHs are typically very large running into several MB
    for windows apps; writing a PCH out is expensive but loading it isn't since
    it's just mapped into memory and paged in as needed. Hence the best
    strategy to improve build times is to gather all headers into an "all.h"
    header and build a PCH for this and use it in all the compilands. You'll
    have to make changes to your codegen tool for this, but I'm sure you'll be
    amazed at the performance gain.

    --
    Tanveer Gani, Microsoft Visual C++ Team
    This posting is provided "AS IS" with no warranties, and confers no rights.
    Use of included script samples are subject to the terms specified at
    http://www.microsoft.com/info/cpyright.htm


    Comment

    • Andrew Ward

      #3
      Re: Precompiled header usage


      "Tanveer Gani [MSFT]" <tgani@online.m icrosoft.com> wrote in message
      news:qkkDx8VeDH A.1112@cpmsftng xa06.phx.gbl...[color=blue]
      >
      > --------------------[color=green]
      > >From: "Andrew Ward" <anwar@ihug.co. nz>
      > >References: <ury7e20dDHA.18 32@TK2MSFTNGP09 .phx.gbl>[/color]
      > <uw6G2F1dDHA.10 08@TK2MSFTNGP12 .phx.gbl>[color=green]
      > >Subject: Re: Precompiled header usage
      > >Date: Wed, 10 Sep 2003 17:26:22 +1200
      > >Lines: 65
      > >X-Priority: 3
      > >X-MSMail-Priority: Normal
      > >X-Newsreader: Microsoft Outlook Express 6.00.2800.1106
      > >X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2800.1106
      > >Message-ID: <ea9qYw1dDHA.19 32@TK2MSFTNGP10 .phx.gbl>
      > >Newsgroups: microsoft.publi c.dotnet.langua ges.vc
      > >NNTP-Posting-Host: 210-54-80-239.dialup.xtra .co.nz 210.54.80.239
      > >Path: cpmsftngxa06.ph x.gbl!TK2MSFTNG P08.phx.gbl!TK2 MSFTNGP10.phx.g bl
      > >Xref: cpmsftngxa06.ph x.gbl microsoft.publi c.dotnet.langua ges.vc:28151
      > >X-Tomcat-NG: microsoft.publi c.dotnet.langua ges.vc
      > >
      > >Hi Brandon,
      > >The problem I am facing is that I cannot add #include "all.h" or whatever[/color]
      > to[color=green]
      > >each source file in the project. About half of the source that is[/color][/color]
      compiled[color=blue][color=green]
      > >for the project is c++ generated from XML specifications, this source is[/color]
      > all[color=green]
      > >generated automatically in the build process.
      > >
      > >An approach like the following would be great for my type of build
      > >environment:
      > >
      > >Each time the compiler encounters an #include <xyz.h> directive it checks[/color][/color]
      a[color=blue][color=green]
      > >cache to see if it has a precompiled version of the header 'xyz.pch' that[/color]
      > is[color=green]
      > >up to date, if one is found then it is used, otherwise a new precompiled
      > >header is created 'xyz.pch' and put in the cache.
      > >
      > >It seems to me that this approach would be more efficient as well,[/color][/color]
      because[color=blue][color=green]
      > >each file being compiled would only include the precompiled data that it
      > >needs, instead of the norm of loading a huge precompiled header for every
      > >source file, whether the file needs all the data or not.
      > >
      > >Is anything of this sort possible?
      > >
      > >
      > >"Brandon Bray [MSFT]" <branbray@onlin e.microsoft.com > wrote in message
      > >news:uw6G2F1dD HA.1008@TK2MSFT NGP12.phx.gbl.. .[color=darkred]
      > >> Andrew Ward wrote:
      > >> > Hi All,
      > >> > I was wondering if it is possible to use precompiled headers without
      > >> > having to include a <stdafx.h> or whatever in every source file.
      > >> > My problem is that I have a project that makes heavy usage of a large
      > >> > third party library which means after pre-processing each translation
      > >> > unit is around 1meg in size. There are reasons though why I cannot[/color][/color][/color]
      use[color=blue][color=green][color=darkred]
      > >> > the standard approach to precompiled headers.
      > >> >
      > >> > What I would like to do is somthing like this:
      > >> > 1) create a header that includes all headers from third party library
      > >> > 2) compile this into a .pch file
      > >> > 3) have VS use this .pch file while compiling any source file it
      > >> > encounters
      > >> >
      > >> > Is this possible?
      > >>
      > >> Hi Andy,
      > >> What you'd like to do is very easy. To create a precompiled header,[/color]
      > >simply[color=darkred]
      > >> tell the compiler which header that should be. Use the /Yc command-line
      > >> switch to do that. Then when you want to use that precompiled header,[/color][/color][/color]
      use[color=blue][color=green][color=darkred]
      > >> the /Yu switch.
      > >>
      > >> The precompiled header needs to be the first #include in the file.
      > >>
      > >> The only reason that you would need to use stdafx.h for that is because
      > >> Visual Studio sets up projects to do this by default. You can of course
      > >> change that. Go to your project properties to change which file the[/color]
      > >project[color=darkred]
      > >> uses.
      > >>
      > >> I hope that makes sense. Cheerio!
      > >>
      > >> --
      > >> Brandon Bray Visual C++[/color][/color][/color]
      Compiler[color=blue][color=green][color=darkred]
      > >> This posting is provided AS IS with no warranties, and confers no[/color][/color][/color]
      rights.[color=blue][color=green][color=darkred]
      > >>
      > >>[/color]
      > >
      > >
      > >[/color]
      >
      > Andy,
      >
      > You seem to have misunderstood the VC++ PCH mechanism. The PCH is not a
      > more compact form of the header. It's really a dump of the compiler's
      > symbol table at the #include point in a source file. When compiling a file
      > with the same #include, the compiler can be made to load the PCH (really
      > the symbol table) the assumption being that the internal state is now the
      > same as if the #include had been processed at that point.
      >
      > You can make the compiler use a different PCH for each compiland, but the
      > obvious advantage is when several compilands share a certain set of files.
      > Then a PCH gets built once and re-used multiple times in a build. Building
      > a PCH per file will save you time only if you're building the same file
      > over and over, but PCHs are typically very large running into several MB
      > for windows apps; writing a PCH out is expensive but loading it isn't[/color]
      since[color=blue]
      > it's just mapped into memory and paged in as needed. Hence the best
      > strategy to improve build times is to gather all headers into an "all.h"
      > header and build a PCH for this and use it in all the compilands. You'll
      > have to make changes to your codegen tool for this, but I'm sure you'll be
      > amazed at the performance gain.
      >
      > --
      > Tanveer Gani, Microsoft Visual C++ Team
      > This posting is provided "AS IS" with no warranties, and confers no[/color]
      rights.[color=blue]
      > Use of included script samples are subject to the terms specified at
      > http://www.microsoft.com/info/cpyright.htm
      >
      >[/color]

      Hi Tanveer, thanks for your response. There is at least one compiler that
      implements it's precompiled-header support in the way I described (gcc) ,
      that is why I asked.
      The problem with your "all.h" approach is that my software has to be
      compiled on many platforms, using different compilers. Some of which have no
      precompiled-header support. This means if I were to use the "all.h" method
      the compile times for other compilers that have no pch support would
      skyrocket.
      I believe that something such as pch support should not govern the way you
      write your code, the fact the MS' pch support requires you to write your
      code in a non efficient way is bad design.


      Andy


      Comment

      • Brandon Bray [MSFT]

        #4
        Re: Precompiled header usage

        Andrew Ward wrote:[color=blue]
        > Hi Tanveer, thanks for your response. There is at least one compiler that
        > implements it's precompiled-header support in the way I described (gcc) ,
        > that is why I asked.[/color]

        Hi Andy,
        It would be helpful if you were able to provide more detail on what GCC
        feature you are using (or provide a link to some place that has
        documentation without a license). To my knowledge (from discussions with
        people who use and work on GCC), pre-compiled headers are not yet a feature
        on GCC. I could be wrong, and would enjoy learning more about it.
        [color=blue]
        > The problem with your "all.h" approach is that my software has to be
        > compiled on many platforms, using different compilers. Some of which have
        > no precompiled-header support. This means if I were to use the "all.h"
        > method the compile times for other compilers that have no pch support
        > would skyrocket.[/color]

        This isn't necessarily true. If this approach were used under an #ifdef
        dependent on _MSC_VER, you could write code that compiles efficiently on
        several platforms. There are very few cross-platform libraries that do not
        make adjustments for particular compilers.
        [color=blue]
        > I believe that something such as pch support should not govern the way you
        > write your code, the fact the MS' pch support requires you to write your
        > code in a non efficient way is bad design.[/color]

        I don't particularly think what Tanveer suggested was a bad design. In some
        regards, it prevents excessive refactoring that often gets developers in to
        trouble when different definitions are introduced for the same type. In any
        case, I hope you can try writing something dependent on _MSC_VER that allows
        you to succeed at your task.

        Cheerio!

        --
        Brandon Bray Visual C++ Compiler
        This posting is provided AS IS with no warranties, and confers no rights.


        Comment

        • David Olsen

          #5
          Re: Precompiled header usage

          Brandon Bray [MSFT] wrote:[color=blue]
          > I don't particularly think what Tanveer suggested was a bad design. In some
          > regards, it prevents excessive refactoring that often gets developers in to
          > trouble when different definitions are introduced for the same type. In any
          > case, I hope you can try writing something dependent on _MSC_VER that allows
          > you to succeed at your task.[/color]

          I think Microsoft's precompiled headers is a bad design. In my opinion,
          a header file should #include exactly what it needs (no more, no less)
          so that it can be compiled by itself. This puts all the #include
          dependencies exactly where they should be. Precompiled headers
          encourages a design where header files do not include anything (or very
          little), but instead rely on certain things already having been included
          earlier in the compilation.

          It also bugs me that precompiled headers is not just an optimization,
          but can change the semantics of the program being compiled. For
          example, if a .cpp file starts with:

          #define PRECOMPILED_HEA DERS_OFF
          #include "stdafx.h"

          Then PRECOMPILED_HEA DERS_OFF will be defined if the project doesn't use
          precompiled headers, but won't be defined if precompiled headers are
          turned on.

          I understand that implementing precompiled headers correctly and
          efficiently without the restrictions Microsoft imposes is an extremely
          hard problem. (In a previous job I actually looked into doing it.) So
          I don't begrudge Microsoft for not doing it. But because they encourage
          bad design I don't use precompiled headers in any of my projects until
          the compilation times become completely unbearable. (Fortunately, I
          almost never have to include windows.h.)

          --
          David Olsen
          qg4h9ykc5m@yaho o.com

          Comment

          Working...