Header include order

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Derrick Coetzee

    Header include order

    It seems like, in every C source file I've ever seen, there has been a
    very definite include order, as follows:

    - include system headers
    - include application headers
    - include the header associated with this source file

    For example, in a file hello.c:

    #include <stdio.h>
    #include "utils.h"
    #include "hello.h"

    (Incidentally I think that a source file which doesn't include the header
    file which exports its symbols is _very_ bad, as this is a good way to
    check for inconsistencies for free.)

    I would argue that the standard order of header including is wrong,
    and that the correct order is the reverse. Consider this scenario:

    hello.c:
    #include <stdlib.h>
    #include "hello.h"

    hello.h:
    struct blah {
    size_t size;
    };

    hello2.c
    #include "hello.h"

    Inexplicably (from the perspective of the person doing the including)
    the file hello.h will cause compiler errors in hello2.c but not in hello.c.
    If hello.c were written first, and then the include file used elsewhere,
    the error would appear to be "new", and not be caught by those who wrote
    hello.c, implementing the functionality exported by hello.h.

    If this include order is used, this problem is averted:

    - include the header associated with this source file
    - include application headers
    - include system headers

    This is good for two reasons:
    1. All headers must now include any system headers they need, and will
    fail immediately if they don't.
    2. Every header will be included in at least ONE source file before
    anything else (the source file associated with that header), allowing
    any intra-application dependencies to be caught.

    Does anyone have a reasonable justification for the standard include
    order that I haven't thought of? Thanks.

    --
    Derrick Coetzee


  • Morris Dovey

    #2
    Re: Header include order

    Derrick Coetzee wrote:
    [color=blue]
    > It seems like, in every C source file I've ever seen, there has been a
    > very definite include order, as follows:
    >
    > - include system headers
    > - include application headers
    > - include the header associated with this source file[/color]

    You have a good eye.[color=blue]
    >
    > For example, in a file hello.c:
    >
    > #include <stdio.h>
    > #include "utils.h"
    > #include "hello.h"
    >
    > (Incidentally I think that a source file which doesn't include the header
    > file which exports its symbols is _very_ bad, as this is a good way to
    > check for inconsistencies for free.)[/color]

    Hmm. Ok. I think that it depends on the situation; but if you
    don't do what you think is bad, you probably won't be wrong.
    [color=blue]
    > I would argue that the standard order of header including is wrong,
    > and that the correct order is the reverse. Consider this scenario:[/color]

    Let me break in here to suggest that it isn't unusual for my
    headers to need definitions provided by the system headers...
    [color=blue]
    > hello.c:
    > #include <stdlib.h>
    > #include "hello.h"
    >
    > hello.h:
    > struct blah {
    > size_t size;
    > };[/color]

    /This/ is bad practice. Structures, unions, arrays, and variables
    should only be declared - not defined - in header files. Placing
    definitions in header files, while not strictly illegal, is
    asking for trouble.
    [color=blue]
    > hello2.c
    > #include "hello.h"
    >
    > Inexplicably (from the perspective of the person doing the including)
    > the file hello.h will cause compiler errors in hello2.c but not in hello.c.
    > If hello.c were written first, and then the include file used elsewhere,
    > the error would appear to be "new", and not be caught by those who wrote
    > hello.c, implementing the functionality exported by hello.h.[/color]

    <snip>
    [color=blue]
    > Does anyone have a reasonable justification for the standard include
    > order that I haven't thought of?[/color]

    Already answered.

    HTH
    --
    Morris Dovey
    West Des Moines, Iowa USA
    C links at http://www.iedu.com/c
    Read my lips: The apple doesn't fall far from the tree.

    Comment

    • Rouben Rostamian

      #3
      Re: Header include order

      In article <Pine.LNX.4.44. 0311182138520.1 4795-100000@semaphor e.moonflare.com >,
      Derrick Coetzee <dcnews@moonfla re.com> wrote:[color=blue]
      >It seems like, in every C source file I've ever seen, there has been a
      >very definite include order, as follows:
      >
      >- include system headers
      >- include application headers
      >- include the header associated with this source file[/color]

      [description of pitfalls snipped]
      [color=blue]
      >If this include order is used, this problem is averted:
      >
      >- include the header associated with this source file
      >- include application headers
      >- include system headers[/color]

      I completely agree with your reasons for suggesting this.
      They make good sense and enforce good code design.

      But old habits die hard. I just can't bring myself to
      reverse the order of header, despite reason and logic.

      Old dog, new tricks...

      --
      Rouben Rostamian

      Comment

      • Morris Dovey

        #4
        Re: Header include order

        Morris Dovey wrote:
        [color=blue][color=green]
        >> hello.h:
        >> struct blah {
        >> size_t size;
        >> };[/color]
        >
        > /This/ is bad practice. Structures, unions, arrays, and variables should
        > only be declared - not defined - in header files. Placing definitions in
        > header files, while not strictly illegal, is asking for trouble.[/color]

        Please ignore the comment about bad practice. Due to faulty
        wiring I read that as a definition, which it obviously isn't.

        If you ignore that, then the remainder is valid ( but not much
        called-for )-:

        --
        Morris Dovey
        West Des Moines, Iowa USA
        C links at http://www.iedu.com/c
        Read my lips: The apple doesn't fall far from the tree.

        Comment

        • Richard Heathfield

          #5
          Re: Header include order

          [This is a rather interesting idea, which probably won't get the attention
          it deserves because it proposes a change to the way code is laid out, and
          many clc-ers don't seem to like such changes.]

          Derrick Coetzee wrote:
          [color=blue]
          > If this include order is used, this [idempotency failure] problem is[/color]
          averted:[color=blue]
          >
          > - include the header associated with this source file
          > - include application headers
          > - include system headers
          >
          > This is good for two reasons:
          > 1. All headers must now include any system headers they need, and will
          > fail immediately if they don't.[/color]

          Not quite true. All headers must either include any system headers they
          need, or follow another such header in the batting order. You have reduced
          the scale of the problem (and I think that's a good thing in itself), but
          not eliminated it.
          [color=blue]
          > 2. Every header will be included in at least ONE source file before
          > anything else (the source file associated with that header), allowing
          > any intra-application dependencies to be caught.[/color]

          Interesting point.
          [color=blue]
          > Does anyone have a reasonable justification for the standard include
          > order that I haven't thought of? Thanks.[/color]

          Only a philosophical one, which hadn't really occurred to me until you
          raised the subject. I think the existing order is as it is because it gives
          a constant narrowing of focus. "Right, let's have some big old headers, our
          good friends stdio, stdlib, string... Okay, now let's pull in some local
          stuff that we used on XFoo... xfoo.h, xbar.h... now, for /this/ program
          we'll need ybaz.h, which we'll write in a minute... okay, let's write
          ybaz".

          In other words, I think it's pure habit.

          --
          Richard Heathfield : binary@eton.pow ernet.co.uk
          "Usenet is a strange place." - Dennis M Ritchie, 29 July 1999.
          C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
          K&R answers, C books, etc: http://users.powernet.co.uk/eton

          Comment

          • Moosebumps

            #6
            Re: Header include order

            > If this include order is used, this problem is averted:[color=blue]
            >
            > - include the header associated with this source file
            > - include application headers
            > - include system headers[/color]

            It's a coding standard at my company (not widely followed) to do this.
            Always #include Foo.h as the first line of Foo.c. That way you're assured
            that whenever you #include Foo.h from any other file, it will compile.
            There is no messing with the orders of headers to fix compile errors, and
            conversely organizing headers for aesthetics will not cause any compile
            errors.




            Comment

            • Jarno A Wuolijoki

              #7
              Re: Header include order

              On Tue, 18 Nov 2003, Derrick Coetzee wrote:
              [color=blue]
              > I would argue that the standard order of header including is wrong,
              > and that the correct order is the reverse.
              > If this include order is used, this problem is averted:
              >
              > - include the header associated with this source file
              > - include application headers
              > - include system headers
              >
              > Does anyone have a reasonable justification for the standard include
              > order that I haven't thought of? Thanks.[/color]

              You may forget to include stdlib in hello.c and
              then when you change hello.h to use stddef instead
              it breaks?

              Comment

              • Dan Pop

                #8
                Re: Header include order

                In <kpBub.610$436. 68836@news.uswe st.net> Morris Dovey <mrdovey@iedu.c om> writes:
                [color=blue]
                >Derrick Coetzee wrote:
                >[color=green]
                >> It seems like, in every C source file I've ever seen, there has been a
                >> very definite include order, as follows:
                >>
                >> - include system headers
                >> - include application headers
                >> - include the header associated with this source file[/color]
                >
                >You have a good eye.[color=green]
                >>
                >> For example, in a file hello.c:
                >>
                >> #include <stdio.h>
                >> #include "utils.h"
                >> #include "hello.h"
                >>
                >> (Incidentally I think that a source file which doesn't include the header
                >> file which exports its symbols is _very_ bad, as this is a good way to
                >> check for inconsistencies for free.)[/color]
                >
                >Hmm. Ok. I think that it depends on the situation; but if you
                >don't do what you think is bad, you probably won't be wrong.
                >[color=green]
                >> I would argue that the standard order of header including is wrong,
                >> and that the correct order is the reverse. Consider this scenario:[/color]
                >
                >Let me break in here to suggest that it isn't unusual for my
                >headers to need definitions provided by the system headers...[/color]

                Then, your headers should include the system headers they need.
                I couldn't agree more with the OP on this point.
                [color=blue][color=green]
                >> hello.h:
                >> struct blah {
                >> size_t size;
                >> };[/color]
                >
                >/This/ is bad practice. Structures, unions, arrays, and variables
                >should only be declared - not defined - in header files. Placing
                >definitions in header files, while not strictly illegal, is
                >asking for trouble.[/color]

                Sheer nonsense, as far as structure and union definitions are concerned.
                When I need a struct tm, I use the definition provided by <time.h> and
                that never caused my any trouble. Using my own definition, OTOH, would
                be a sure recipe for headaches.

                Dan
                --
                Dan Pop
                DESY Zeuthen, RZ group
                Email: Dan.Pop@ifh.de

                Comment

                • Dan Pop

                  #9
                  Re: Header include order

                  In <Pine.LNX.4.44. 0311182138520.1 4795-100000@semaphor e.moonflare.com > Derrick Coetzee <dcnews@moonfla re.com> writes:
                  [color=blue]
                  >It seems like, in every C source file I've ever seen, there has been a
                  >very definite include order, as follows:
                  >
                  >- include system headers
                  >- include application headers
                  >- include the header associated with this source file
                  >
                  >For example, in a file hello.c:
                  >
                  >#include <stdio.h>
                  >#include "utils.h"
                  >#include "hello.h"
                  >
                  >(Incidentall y I think that a source file which doesn't include the header
                  > file which exports its symbols is _very_ bad, as this is a good way to
                  > check for inconsistencies for free.)[/color]

                  Obviously.
                  [color=blue]
                  >I would argue that the standard order of header including is wrong,
                  >and that the correct order is the reverse. Consider this scenario:
                  >
                  >hello.c:
                  >#include <stdlib.h>
                  >#include "hello.h"
                  >
                  >hello.h:
                  >struct blah {
                  > size_t size;
                  >};
                  >
                  >hello2.c
                  >#include "hello.h"
                  >
                  >Inexplicably (from the perspective of the person doing the including)
                  >the file hello.h will cause compiler errors in hello2.c but not in hello.c.[/color]

                  It's not inexplicable. If hello.h is written this way, then including
                  <stddef.h> must be documented as a prerequisite. I agree that this is
                  not the right way of defining hello.h, *these days*.
                  [color=blue]
                  >If this include order is used, this problem is averted:
                  >
                  >- include the header associated with this source file
                  >- include application headers
                  >- include system headers
                  >
                  >This is good for two reasons:
                  >1. All headers must now include any system headers they need, and will[/color]
                  ^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^ ^^^^^^^^^^^^[color=blue]
                  >fail immediately if they don't.[/color]

                  This is a general rule, *these days*. The system headers are not included
                  first so that other headers no longer have to include them.
                  [color=blue]
                  >2. Every header will be included in at least ONE source file before
                  >anything else (the source file associated with that header), allowing
                  >any intra-application dependencies to be caught.[/color]

                  This is a valid point.
                  [color=blue]
                  >Does anyone have a reasonable justification for the standard include
                  >order that I haven't thought of? Thanks.[/color]

                  Yes, from a historical perspective. Back when disks were much slower
                  than they are today (especially on micros and low end minis, whose
                  fastest mass storage devices were floppy disks), you didn't want to
                  have to open and read any more header files than strictly necessary.
                  Therefore, headers didn't include other headers, they merely documented
                  their dependencies. Using the traditional include order, each header file
                  had to be opened and read exactly once, speeding up the compilation
                  process, at the expense of some extra care on the programmer's side.

                  But there is another reason, that still applies. It is very easy to
                  inadvertently declare an identifier already declared in a system header.
                  Especially if your implementation provides many C99 functions as
                  extensions, along with its own specific extensions. If you include
                  the application headers first, the compiler will report the problem
                  as being generated by a system header. I've seen more than one
                  programmer completely baffled when that happened and suspecting his
                  implementation to be broken, because including a system header must,
                  "by definition", cause no problems. Imagine the following scenario:
                  one of your headers, say "appmath.h" , declares:

                  long round(double);

                  and everything works fine, until someone else tries to compile your
                  program on a platform declaring

                  double round(double);

                  as a C99 extension in <math.h> (or even having C99 conforming libraries).
                  Since <math.h> was included after the application header, the error
                  will be reported in <math.h>, resulting in a maximum of confusion
                  (especially if the compiler was not kind enough to indicate the
                  actual location of the other declaration). Now, if that happened in
                  "appmath.h" , nobody would expect the system headers to be broken, because
                  the problem is correctly reported as belonging to "appmath.h" .

                  So, going from more general to more specific still has its merits...

                  Dan
                  --
                  Dan Pop
                  DESY Zeuthen, RZ group
                  Email: Dan.Pop@ifh.de

                  Comment

                  • Morris Dovey

                    #10
                    Re: Header include order

                    Dan Pop wrote:[color=blue]
                    > Morris Dovey wrote:[color=green]
                    >>Let me break in here to suggest that it isn't unusual for my
                    >>headers to need definitions provided by the system headers...[/color]
                    >
                    > Then, your headers should include the system headers they need.
                    > I couldn't agree more with the OP on this point.[/color]

                    Me too. It /does/ look as if I'd have done better to turn off the
                    computer and get some sleep. Apologies to Derrick.
                    [color=blue][color=green]
                    >>/This/ is bad practice. Structures, unions, arrays, and variables
                    >>should only be declared - not defined - in header files. Placing
                    >>definitions in header files, while not strictly illegal, is
                    >>asking for trouble.[/color][/color]
                    [color=blue]
                    > Sheer nonsense, as far as structure and union definitions are concerned.
                    > When I need a struct tm, I use the definition provided by <time.h> and
                    > that never caused my any trouble. Using my own definition, OTOH, would
                    > be a sure recipe for headaches.[/color]

                    More of the same. This bit of stupidity I /did/ catch last night.
                    Now I find myself wondering what I could have been thinking. I
                    swear I was only drinking coffee...
                    --
                    Morris Dovey
                    West Des Moines, Iowa USA
                    C links at http://www.iedu.com/c
                    Read my lips: The apple doesn't fall far from the tree.

                    Comment

                    • Alan Balmer

                      #11
                      Re: Header include order

                      On 19 Nov 2003 12:53:29 GMT, Dan.Pop@cern.ch (Dan Pop) wrote:
                      [color=blue][color=green]
                      >>Let me break in here to suggest that it isn't unusual for my
                      >>headers to need definitions provided by the system headers...[/color]
                      >
                      >Then, your headers should include the system headers they need.
                      >I couldn't agree more with the OP on this point.
                      >[/color]
                      Me, too :-) The standard headers, particularly, are guaranteed to work
                      in any order and even if included more than once.
                      [color=blue][color=green][color=darkred]
                      >>> hello.h:
                      >>> struct blah {
                      >>> size_t size;
                      >>> };[/color]
                      >>
                      >>/This/ is bad practice. Structures, unions, arrays, and variables
                      >>should only be declared - not defined - in header files. Placing
                      >>definitions in header files, while not strictly illegal, is
                      >>asking for trouble.[/color]
                      >
                      >Sheer nonsense, as far as structure and union definitions are concerned.
                      >When I need a struct tm, I use the definition provided by <time.h> and
                      >that never caused my any trouble. Using my own definition, OTOH, would
                      >be a sure recipe for headaches.
                      >[/color]
                      Definition vs. declaration?

                      I prefer that nothing in a header file reserve storage.

                      The above is OK, but a header file containing

                      struct blah {
                      size_t size;
                      } xyz;

                      is bad practice, imo.

                      --
                      Al Balmer
                      Balmer Consulting
                      removebalmercon sultingthis@att .net

                      Comment

                      • Dan Pop

                        #12
                        Re: Header include order

                        In <jrbnrvgaq59vgp h8c2nb73jq8ufhv 9999m@4ax.com> Alan Balmer <albalmer@att.n et> writes:
                        [color=blue]
                        >On 19 Nov 2003 12:53:29 GMT, Dan.Pop@cern.ch (Dan Pop) wrote:
                        >[color=green][color=darkred]
                        >>>Let me break in here to suggest that it isn't unusual for my
                        >>>headers to need definitions provided by the system headers...[/color]
                        >>
                        >>Then, your headers should include the system headers they need.
                        >>I couldn't agree more with the OP on this point.
                        >>[/color]
                        >Me, too :-) The standard headers, particularly, are guaranteed to work
                        >in any order and even if included more than once.
                        >[color=green][color=darkred]
                        >>>> hello.h:
                        >>>> struct blah {
                        >>>> size_t size;
                        >>>> };
                        >>>
                        >>>/This/ is bad practice. Structures, unions, arrays, and variables
                        >>>should only be declared - not defined - in header files. Placing
                        >>>definition s in header files, while not strictly illegal, is
                        >>>asking for trouble.[/color]
                        >>
                        >>Sheer nonsense, as far as structure and union definitions are concerned.
                        >>When I need a struct tm, I use the definition provided by <time.h> and
                        >>that never caused my any trouble. Using my own definition, OTOH, would
                        >>be a sure recipe for headaches.
                        >>[/color]
                        >Definition vs. declaration?[/color]

                        When it comes to structures and unions (as types, not as objects), I
                        consider:

                        struct foo;

                        to be a declaration and:

                        struct foo { int bar, baz; };

                        to be a definition.
                        [color=blue]
                        >I prefer that nothing in a header file reserve storage.[/color]

                        It's more than a simple preference in my case :-)

                        Dan
                        --
                        Dan Pop
                        DESY Zeuthen, RZ group
                        Email: Dan.Pop@ifh.de

                        Comment

                        • Arthur J. O'Dwyer

                          #13
                          Re: Header include order


                          On Thu, 20 Nov 2003, CBFalconer wrote:[color=blue]
                          >
                          > "E. Robert Tisdale" wrote:[color=green]
                          > >
                          > > You are confused.
                          > > A file included by the C preprocessor directive
                          > > is *not* necessarily a header file.
                          > > A file with *.h extension is *not* necessarily a header file.
                          > > Neither the C preprocessor or the C programming language
                          > > specify file name extensions for header files.[/color]
                          >
                          > We should take especial notice now. That omniscient expert, ERT,
                          > has made his pronouncement. Since he specifies his organization
                          > as "Jet Propulsion Laboratory", and his return address as
                          > @jpl.nasa.gov, he carries very imposing credentials. After all,
                          > his abilities and careful standards adherence and understanding
                          > are obviously protecting the entire US space program. The utter
                          > drivel posted in c.l.c under his name is obviously a concerted
                          > plot by the evil (left/right/center) to undermine his shining
                          > reputation.[/color]

                          Chuck, as much as ERT has trolled and misinformed before, I
                          must say that your post looks uncalled-for here. I think he's
                          right -- a "header file," as the term is commonly used, refers
                          to a file that is included at the top of another file, and
                          contains declarations and macros and suchlike.
                          A file included in the middle of another file, containing
                          data or code templates, is *not* a "header file" -- it's a
                          "data file" or a "code template file."
                          FWIW, the Standard explicitly mentions that

                          [an] #include preprocessing
                          directive causes the named header or source file to be
                          ^^^^^^^^^^^^^^
                          processed from phase 1 through phase 4, recursively.

                          by which I gather that the committee had something of the
                          same idea in mind. Makes sense to me, anyway.

                          So, let's leave the name-calling for the defenses of 'void
                          main' and 'malloc' casting, announcements of 'obvious trolls',
                          and indictments of 'indigenous plonkers', huh? :-) IMHO
                          Tisdale is right for once.

                          -Arthur

                          Comment

                          • Richard Heathfield

                            #14
                            Re: Header include order

                            EventHelix.com wrote:
                            [color=blue]
                            > For header file includes
                            >
                            > a.c file should always include a.h as the first file. That way
                            > a.h will always be self sufficient and header file include order
                            > will not matter.
                            >
                            > The following article should help:
                            >
                            > http://www.eventhelix.com/RealtimeMa...dePatterns.htm[/color]

                            I doubt it. It's chock-full of syntax errors and undefined behaviour. Quite
                            a trick for a header file.

                            #ifndef _a_h_included_
                            #define _a_h_included_

                            It's a bad idea to use leading underscores.

                            #include "abase.h"
                            #include "b.h"

                            No source, no comment.

                            // Forward Declarations

                            Syntax error in C90.

                            class C;

                            Presumably class is typedef'd in abase.h or b.h?

                            class D;

                            class A : public ABase

                            And that's a syntax error.

                            Not a great page, IMHO.

                            --
                            Richard Heathfield : binary@eton.pow ernet.co.uk
                            "Usenet is a strange place." - Dennis M Ritchie, 29 July 1999.
                            C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
                            K&R answers, C books, etc: http://users.powernet.co.uk/eton

                            Comment

                            • Moosebumps

                              #15
                              Re: Header include order

                              Good article, that's exactly what I do... took a while to pick that pattern
                              up, since I haven't seen it mentioned in a lot of C/C++ books. Some of my
                              coworkers still don't know when to use forward declarations.

                              "EventHelix.com " <eventhelix@hot mail.com> wrote in message
                              news:566e2bfb.0 311191923.783eb 44f@posting.goo gle.com...[color=blue]
                              > For header file includes
                              >
                              > a.c file should always include a.h as the first file. That way
                              > a.h will always be self sufficient and header file include order
                              > will not matter.
                              >
                              > The following article should help:
                              >
                              > http://www.eventhelix.com/RealtimeMa...dePatterns.htm
                              >
                              > Sandeep
                              > --
                              > http://www.EventHelix.com/EventStudio
                              > EventStudio 2.0 - Generate Message Sequence Charts in PDF[/color]


                              Comment

                              Working...