Header include order

Discussion in 'C Programming' started by Derrick Coetzee, Nov 19, 2003.

  1. 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
    Derrick Coetzee, Nov 19, 2003
    #1
    1. Advertising

  2. Derrick Coetzee

    Morris Dovey Guest

    Derrick Coetzee wrote:

    > 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


    You have a good eye.
    >
    > 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.)


    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.

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


    Let me break in here to suggest that it isn't unusual for my
    headers to need definitions provided by the system headers...

    > hello.c:
    > #include <stdlib.h>
    > #include "hello.h"
    >
    > 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
    definitions in header files, while not strictly illegal, is
    asking for trouble.

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


    <snip>

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


    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.
    Morris Dovey, Nov 19, 2003
    #2
    1. Advertising

  3. In article <>,
    Derrick Coetzee <> wrote:
    >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


    [description of pitfalls snipped]

    >If this include order is used, this problem is averted:
    >
    >- include the header associated with this source file
    >- include application headers
    >- include system headers


    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
    Rouben Rostamian, Nov 19, 2003
    #3
  4. Derrick Coetzee

    Morris Dovey Guest

    Morris Dovey wrote:

    >> 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 definitions in
    > header files, while not strictly illegal, is asking for trouble.


    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.
    Morris Dovey, Nov 19, 2003
    #4
  5. [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:

    > If this include order is used, this [idempotency failure] 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.


    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.

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


    Interesting point.

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


    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 :
    "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
    Richard Heathfield, Nov 19, 2003
    #5
  6. Derrick Coetzee

    Moosebumps Guest

    > If this include order is used, this problem is averted:
    >
    > - include the header associated with this source file
    > - include application headers
    > - include system headers


    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.
    Moosebumps, Nov 19, 2003
    #6
  7. On Tue, 18 Nov 2003, Derrick Coetzee wrote:

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


    You may forget to include stdlib in hello.c and
    then when you change hello.h to use stddef instead
    it breaks?
    Jarno A Wuolijoki, Nov 19, 2003
    #7
  8. Derrick Coetzee

    Dan Pop Guest

    In <kpBub.610$> Morris Dovey <> writes:

    >Derrick Coetzee wrote:
    >
    >> 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

    >
    >You have a good eye.
    >>
    >> 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.)

    >
    >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.
    >
    >> I would argue that the standard order of header including is wrong,
    >> and that the correct order is the reverse. Consider this scenario:

    >
    >Let me break in here to suggest that it isn't unusual for my
    >headers to need definitions provided by the system headers...


    Then, your headers should include the system headers they need.
    I couldn't agree more with the OP on this point.

    >> 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
    >definitions in header files, while not strictly illegal, is
    >asking for trouble.


    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, Nov 19, 2003
    #8
  9. Derrick Coetzee

    Dan Pop Guest

    In <> Derrick Coetzee <> writes:

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


    Obviously.

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


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

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


    This is a general rule, *these days*. The system headers are not included
    first so that other headers no longer have to include them.

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


    This is a valid point.

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


    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, Nov 19, 2003
    #9
  10. Derrick Coetzee

    Morris Dovey Guest

    Dan Pop wrote:
    > Morris Dovey wrote:
    >>Let me break in here to suggest that it isn't unusual for my
    >>headers to need definitions provided by the system headers...

    >
    > Then, your headers should include the system headers they need.
    > I couldn't agree more with the OP on this point.


    Me too. It /does/ look as if I'd have done better to turn off the
    computer and get some sleep. Apologies to Derrick.

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


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


    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.
    Morris Dovey, Nov 19, 2003
    #10
  11. Derrick Coetzee

    Alan Balmer Guest

    On 19 Nov 2003 12:53:29 GMT, (Dan Pop) wrote:

    >>Let me break in here to suggest that it isn't unusual for my
    >>headers to need definitions provided by the system headers...

    >
    >Then, your headers should include the system headers they need.
    >I couldn't agree more with the OP on this point.
    >

    Me, too :) The standard headers, particularly, are guaranteed to work
    in any order and even if included more than once.

    >>> 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
    >>definitions in header files, while not strictly illegal, is
    >>asking for trouble.

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

    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
    Alan Balmer, Nov 19, 2003
    #11
  12. Derrick Coetzee

    Dan Pop Guest

    In <> Alan Balmer <> writes:

    >On 19 Nov 2003 12:53:29 GMT, (Dan Pop) wrote:
    >
    >>>Let me break in here to suggest that it isn't unusual for my
    >>>headers to need definitions provided by the system headers...

    >>
    >>Then, your headers should include the system headers they need.
    >>I couldn't agree more with the OP on this point.
    >>

    >Me, too :) The standard headers, particularly, are guaranteed to work
    >in any order and even if included more than once.
    >
    >>>> 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
    >>>definitions in header files, while not strictly illegal, is
    >>>asking for trouble.

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

    >Definition vs. declaration?


    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.

    >I prefer that nothing in a header file reserve storage.


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

    Dan
    --
    Dan Pop
    DESY Zeuthen, RZ group
    Email:
    Dan Pop, Nov 19, 2003
    #12
  13. Derrick Coetzee

    Alan Balmer Guest

    On 19 Nov 2003 18:56:33 GMT, (Dan Pop) wrote:

    >In <> Alan Balmer <> writes:
    >
    >>On 19 Nov 2003 12:53:29 GMT, (Dan Pop) wrote:
    >>
    >>>

    >>Definition vs. declaration?

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

    What do you call

    struct foo foo_thing;

    ?

    Of course, my speculation as to what Morris really meant is outdated,
    since it appears he really meant to get some sleep.

    >>I prefer that nothing in a header file reserve storage.

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


    When writing code, it's an absolute. When maintaining legacy code,
    I've sometimes ignored it if the fix would take too long.

    I'm making progress, though - in the last couple of years at this
    location, the product builds have declined from about 360,000 warnings
    to under 70,000 ;-)

    Still have a bunch of modules that haven't been made compliant enough
    to turn on the ANSI compiler switch.

    --
    Al Balmer
    Balmer Consulting
    Alan Balmer, Nov 19, 2003
    #13
  14. Derrick Coetzee wrote:

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


    Where is the definition for size_t?

    > };
    >
    > 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?


    A header file is a file that you #include
    near the top of a translation unit (or another header file).
    You can #include files at any point in a translation unit
    (or header file) but you probably shouldn't call them header files.

    According to Sun Microsystems,

    http://docs.sun.com/db/doc/805-4955/6j4mg806h?a=view

    header files should be both idempotent and self-contained
    so that it doesn't matter which order you include them
    which reduces your observation to a "coding style" issue.

    I would write

    > cat hello.h
    #ifndef guard_hello_h
    #define guard_hello_h 1
    #include<stdlib.h>
    typedef struct blah {
    size_t size;
    } blah;
    #endif//guard_hello_h

    > cat hello.c
    #include"hello.h"
    // . . .

    As a general rule of thumb, don't put anything in a header file
    that would, by itself, cause the compiler to emit code.
    E. Robert Tisdale, Nov 19, 2003
    #14
  15. Derrick Coetzee

    Alex Guest

    E. Robert Tisdale <> wrote:
    > Derrick Coetzee wrote:


    <snip>

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


    > Where is the definition for size_t?


    <snip>

    > I would write


    > > cat hello.h
    > #ifndef guard_hello_h
    > #define guard_hello_h 1
    > #include<stdlib.h>
    > typedef struct blah {
    > size_t size;
    > } blah;
    > #endif//guard_hello_h


    > > cat hello.c
    > #include"hello.h"
    > // . . .


    Where is the definition for size_t?

    Alex
    Alex, Nov 19, 2003
    #15
  16. Alex wrote:
    > E. Robert Tisdale <> wrote:
    >
    >>Derrick Coetzee wrote:

    >
    >
    > <snip>
    >
    >>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;

    >>

    >
    >>Where is the definition for size_t?

    >
    >
    > <snip>
    >
    >>I would write

    >
    >
    >> > cat hello.h
    >> #ifndef guard_hello_h
    >> #define guard_hello_h 1
    >> #include<stdlib.h>
    >> typedef struct blah {
    >> size_t size;
    >> } blah;
    >> #endif//guard_hello_h

    >
    >
    >> > cat hello.c
    >> #include"hello.h"
    >> // . . .

    >
    >
    > Where is the definition for size_t?


    In a header file included by stdlib.h
    E. Robert Tisdale, Nov 19, 2003
    #16
  17. Derrick Coetzee

    Eric Sosman Guest

    Alan Balmer wrote:
    >
    > On 19 Nov 2003 18:56:33 GMT, (Dan Pop) wrote:
    >
    > >Alan Balmer <> writes:
    > >
    > >>I prefer that nothing in a header file reserve storage.

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

    >
    > When writing code, it's an absolute. When maintaining legacy code,
    > I've sometimes ignored it if the fix would take too long.


    I agree with Dan and Alan for the proverbial 99.44% of
    all uses of header files, but there *are* cases where it
    can be useful to put definitions in headers. A few I've
    run across:

    - When part of the code is generated by a "helper"
    program, it's often convenient to have the helper
    write a header. This is often seen in connection
    with static initializations, where the main file
    contains something like

    static const struct thingummy big_table[] = {
    #include "generated.h"
    };

    There's a quibble about whether the header in this
    case "reserves storage" or not -- but at any rate,
    it certainly doesn't contain declarations!

    - Headers are a good place for widely-used `inline'
    functions. Again, there's a quibble about whether
    defining such a function "reserves storage," but
    again it's clear that such a header contains more
    than mere declarations.

    - "Code generating" or "template" headers can be useful
    in generating functions customized for particular
    data types. For example, I've seen a customizable
    sort generator that's used somewhat like

    void sort_thing(struct thing *array, size_t count)
    {
    #define SORT_TYPE struct thing
    #define SORT_COMPARE(x,y) ((x).key < (y).key)
    #define SORT_ARRAYNAME array
    #define SORT_COUNT count
    #define SORT_ALGORITHM SORT_HEAPSORT
    ...
    #include "sort_generator.h"
    }

    Note that it is quite often difficult or impossible
    to re-package such a code generator as a macro, because
    macros cannot themselves use preprocessor directives
    and this can be limiting in such a situation. (For
    example, consider how to handle the SORT_ALGORITHM
    variation in a pure-macro setting.)

    Still and all, these are exceptional cases and fairly far
    from the norm. 99.44% of all headers, and perhaps more, should
    do as Alan and Dan say.

    --
    Eric Sosman, Nov 19, 2003
    #17
  18. Eric Sosman wrote:
    > Alan Balmer wrote:
    >
    >>On 19 Nov 2003 18:56:33 GMT, (Dan Pop) wrote:
    >>
    >>
    >>>Alan Balmer <> writes:
    >>>
    >>>
    >>>>I prefer that nothing in a header file reserve storage.
    >>>
    >>>It's more than a simple preference in my case :)

    >>
    >>When writing code, it's an absolute. When maintaining legacy code,
    >>I've sometimes ignored it if the fix would take too long.

    >
    >
    > I agree with Dan and Alan for the proverbial 99.44% of
    > all uses of header files, but there *are* cases where it
    > can be useful to put definitions in headers. A few I've
    > run across:
    >
    > - When part of the code is generated by a "helper"
    > program, it's often convenient to have the helper
    > write a header. This is often seen in connection
    > with static initializations, where the main file
    > contains something like
    >
    > static const struct thingummy big_table[] = {
    > #include "generated.h"
    > };


    That's *not* a header file.
    A header file is #included at the *head* of another file.

    >
    > There's a quibble about whether the header in this
    > case "reserves storage" or not -- but at any rate,
    > it certainly doesn't contain declarations!
    >
    > - Headers are a good place for widely-used `inline'
    > functions. Again, there's a quibble about whether
    > defining such a function "reserves storage," but
    > again it's clear that such a header contains more
    > than mere declarations.
    >
    > - "Code generating" or "template" headers can be useful
    > in generating functions customized for particular
    > data types. For example, I've seen a customizable
    > sort generator that's used somewhat like
    >
    > void sort_thing(struct thing *array, size_t count)
    > {
    > #define SORT_TYPE struct thing
    > #define SORT_COMPARE(x,y) ((x).key < (y).key)
    > #define SORT_ARRAYNAME array
    > #define SORT_COUNT count
    > #define SORT_ALGORITHM SORT_HEAPSORT
    > ...
    > #include "sort_generator.h"
    > }


    Again, this is *not* a header file.

    >
    > Note that it is quite often difficult or impossible
    > to re-package such a code generator as a macro, because
    > macros cannot themselves use preprocessor directives
    > and this can be limiting in such a situation. (For
    > example, consider how to handle the SORT_ALGORITHM
    > variation in a pure-macro setting.)
    >
    > Still and all, these are exceptional cases and fairly far
    > from the norm. 99.44% of all headers, and perhaps more, should
    > do as Alan and Dan say.
    >


    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.
    E. Robert Tisdale, Nov 19, 2003
    #18
  19. EventHelix.com, Nov 20, 2003
    #19
  20. > According to Sun Microsystems,
    >
    > http://docs.sun.com/db/doc/805-4955/6j4mg806h?a=view
    >
    > header files should be both idempotent and self-contained
    > so that it doesn't matter which order you include them
    > which reduces your observation to a "coding style" issue.


    I omitted the usual header guards for simplicitly. I fully support the
    idea of each header including whatever other headers it depends
    upon. In fact, the entire point of my post was that the include order
    I advocate makes it easier to catch accidental omissions of other
    headers that should be included from the header. Sorry if that
    wasn't clear.

    > As a general rule of thumb, don't put anything in a header file
    > that would, by itself, cause the compiler to emit code.


    True, but irrelevent.

    --
    Derrick Coetzee
    Derrick Coetzee, Nov 20, 2003
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Soren Kuula
    Replies:
    2
    Views:
    480
    Soren Kuula
    Feb 1, 2004
  2. Aguilar, James
    Replies:
    2
    Views:
    673
    Aguilar, James
    Jul 16, 2004
  3. Marco Spatz

    header include order

    Marco Spatz, Jun 29, 2006, in forum: C++
    Replies:
    1
    Views:
    419
    Bo Persson
    Jun 29, 2006
  4. Andreas Bogenberger
    Replies:
    3
    Views:
    879
    Andreas Bogenberger
    Feb 22, 2008
  5. mlt
    Replies:
    2
    Views:
    810
    Jean-Marc Bourguet
    Jan 31, 2009
Loading...

Share This Page