what is the best way

Discussion in 'C Programming' started by Andre, Nov 27, 2012.

  1. Andre

    Andre Guest

    to organize source in a multi soucres project.
    Is a main.h file with every definition for every sources the best or
    a each.h file for each.c file the best.
    It's a verry loooong time last I used c.
    André
    Andre, Nov 27, 2012
    #1
    1. Advertising

  2. Andre <> writes:

    | what is the best way
    > to organize source in a multi soucres project.
    > Is a main.h file with every definition for every sources the best or
    > a each.h file for each.c file the best.


    The latter is more common and easier to understand later.

    Not every .c file will have a .h file (the file defining main, for
    example, very often will not define anything that other modules need to
    see) and not all .h file will correspond to a .c file (for example a
    .. file that contains nothing but macros, types and inline functions).

    --
    Ben.
    Ben Bacarisse, Nov 27, 2012
    #2
    1. Advertising

  3. On Tuesday, November 27, 2012 3:19:24 PM UTC, Andre wrote:
    > to organize source in a multi soucres project.
    >
    > Is a main.h file with every definition for every sources the best or
    > a each.h file for each.c file the best.
    >

    Arrange the functions logically in modules. Normally you'll only want to
    export a subset of the functions in each module, the others won't make
    any sense except as subroutines to the other functions.
    Put these in a matching .h file. Add #include guards (#ifndef myfile_h
    #define myfile_h /* prototypes here */ #endif ).
    It's better to make each .h includeable on its own. So it needs to internally
    #include any dependencies.

    --
    Vist Malcolm's website
    http://www.malcolmmclean.site11.com/www
    Malcolm McLean, Nov 27, 2012
    #3
  4. Andre

    James Kuyper Guest

    On 11/27/2012 10:19 AM, Andre wrote:
    > to organize source in a multi soucres project.
    > Is a main.h file with every definition for every sources the best or
    > a each.h file for each.c file the best.
    > It's a verry loooong time last I used c.


    There's lots of different ways to do this. My own convention has been to
    create one header file for each module, which will in general contain
    multiple function definitions, but usually only one with external
    linkage. The header file will provide declarations for every identifier
    with external linkage defined in that module. If there are no such
    identifiers (this is often the case for the module which defines
    main()), no header is needed. The header will also contain definitions
    for every typedef and every struct, union, or enumeration needed by
    those declarations. If there are any special values associated with the
    arguments or return value of any of the functions it declares, it will
    #define macros for those values. Every #define and type definition will
    appear explicitly only in one particular header file; they will be
    #included into any other header where needed.
    For libraries, the headers associated with each module in the library
    are used only for compiling those modules. I prepare a special header
    for users of the library, declaring only those identifiers with external
    linkage that users are intended to access, along with the associated
    types and macros.
    James Kuyper, Nov 27, 2012
    #4
  5. Andre

    Les Cargill Guest

    Andre wrote:
    > to organize source in a multi soucres project.
    > Is a main.h file with every definition for every sources the best or
    > a each.h file for each.c file the best.
    > It's a verry loooong time last I used c.
    > André



    There is no "best". Still:

    - Have one header .h per .c file.
    - Have all the #includes needed for that .c file #included in the .h
    file. That way, if there are 7 c files, "grep "#include" *.c | wc " will
    be 7.

    - Have this basic structure:

    thing.h:

    #ifndef _THING_H_
    #define _THING_H_ 1
    ....
    #endif

    guarding all header files.

    - Use "gcc -M *.c > .depend" ( or equivalent ) in your makefile. Then if
    you want, use "source .depend" or "include .depend" at the bottom.

    - Don't have an "includes" or "headers" directory for .h files unless
    you somehow need to.

    All IMO.


    --
    Les Cargill
    Les Cargill, Nov 27, 2012
    #5
  6. Andre

    Ian Collins Guest

    James Kuyper wrote:
    > On 11/27/2012 10:19 AM, Andre wrote:
    >> to organize source in a multi soucres project.
    >> Is a main.h file with every definition for every sources the best or
    >> a each.h file for each.c file the best.
    >> It's a verry loooong time last I used c.

    >
    > There's lots of different ways to do this. My own convention has been to
    > create one header file for each module, which will in general contain
    > multiple function definitions, but usually only one with external
    > linkage.


    Either I'm parsing that wrong, or you've written it wrong. How and why
    would you have a function declaration in a (public) header if it doesn't
    have external linkage?

    --
    Ian Collins
    Ian Collins, Nov 27, 2012
    #6
  7. Andre

    Ian Collins Guest

    Les Cargill wrote:
    > Andre wrote:
    >> to organize source in a multi soucres project.
    >> Is a main.h file with every definition for every sources the best or
    >> a each.h file for each.c file the best.
    >> It's a verry loooong time last I used c.
    >> André

    >
    >
    > There is no "best". Still:
    >
    > - Have one header .h per .c file.


    That isn't necessarily a good idea. If a header declares the interface
    to a module or library, the functions declared in the header are often
    defined in more than one C file.

    How to manage interface declarations and implementations really depends
    on the the complexity of the application and the environment. In most
    large projects I've seen or worked on there are a mix of public and
    module private headers. OS libraries are a good example of this, there
    will be a public header which ends up being part of the end user
    distribution and private headers that never leave the private source tree.

    > - Have all the #includes needed for that .c file #included in the .h
    > file. That way, if there are 7 c files, "grep "#include" *.c | wc " will
    > be 7.


    This practice often causes more trouble than it is worth.

    > - Have this basic structure:
    >
    > thing.h:
    >
    > #ifndef _THING_H_
    > #define _THING_H_ 1


    The 1 is unusual and superfluous.

    --
    Ian Collins
    Ian Collins, Nov 27, 2012
    #7
  8. Andre

    James Kuyper Guest

    On 11/27/2012 02:43 PM, Ian Collins wrote:
    > James Kuyper wrote:
    >> On 11/27/2012 10:19 AM, Andre wrote:
    >>> to organize source in a multi soucres project.
    >>> Is a main.h file with every definition for every sources the best or
    >>> a each.h file for each.c file the best.
    >>> It's a verry loooong time last I used c.

    >>
    >> There's lots of different ways to do this. My own convention has been to
    >> create one header file for each module, which will in general contain
    >> multiple function definitions, but usually only one with external
    >> linkage.

    >
    > Either I'm parsing that wrong, or you've written it wrong. How and why
    > would you have a function declaration in a (public) header if it doesn't
    > have external linkage?


    The "which will ..." clause was describing the module, not the header
    file. I agree that I should have written that more clearly. How about this:

    I generally create modules which may contain multiple function
    definitions, but usually only one with external linkage. My convention
    has been to create one header file for each module.

    Is that better?
    James Kuyper, Nov 27, 2012
    #8
  9. Andre

    Ian Collins Guest

    James Kuyper wrote:
    > On 11/27/2012 02:43 PM, Ian Collins wrote:
    >> James Kuyper wrote:
    >>> On 11/27/2012 10:19 AM, Andre wrote:
    >>>> to organize source in a multi soucres project.
    >>>> Is a main.h file with every definition for every sources the best or
    >>>> a each.h file for each.c file the best.
    >>>> It's a verry loooong time last I used c.
    >>>
    >>> There's lots of different ways to do this. My own convention has been to
    >>> create one header file for each module, which will in general contain
    >>> multiple function definitions, but usually only one with external
    >>> linkage.

    >>
    >> Either I'm parsing that wrong, or you've written it wrong. How and why
    >> would you have a function declaration in a (public) header if it doesn't
    >> have external linkage?

    >
    > The "which will ..." clause was describing the module, not the header
    > file. I agree that I should have written that more clearly. How about this:
    >
    > I generally create modules which may contain multiple function
    > definitions, but usually only one with external linkage. My convention
    > has been to create one header file for each module.
    >
    > Is that better?


    Yes :)

    --
    Ian Collins
    Ian Collins, Nov 27, 2012
    #9
  10. Andre

    Jorgen Grahn Guest

    On Tue, 2012-11-27, Ian Collins wrote:
    > Les Cargill wrote:
    >> Andre wrote:
    >>> to organize source in a multi soucres project.
    >>> Is a main.h file with every definition for every sources the best or
    >>> a each.h file for each.c file the best.
    >>> It's a verry loooong time last I used c.
    >>> André

    >>
    >>
    >> There is no "best". Still:
    >>
    >> - Have one header .h per .c file.

    >
    > That isn't necessarily a good idea. If a header declares the interface
    > to a module or library, the functions declared in the header are often
    > defined in more than one C file.


    I took it to be more of a rule of thumb.

    > How to manage interface declarations and implementations really depends
    > on the the complexity of the application and the environment.

    ....

    >> - Have all the #includes needed for that .c file #included in the .h
    >> file. That way, if there are 7 c files, "grep "#include" *.c | wc " will
    >> be 7.

    >
    > This practice often causes more trouble than it is worth.


    Yes -- that seems highly unusual and impractical. E.g. anyone who
    wants to use the interface provided by foo.h will be poisoned by
    everything needed to implement foo.c!

    Note that this is distinct from the idea of idempotent header files --
    the idea that foo.h doesn't have a secret "shopping list" of other
    header files which must be included first to make '#include "foo.h"'
    compile.

    /Jorgen

    --
    // Jorgen Grahn <grahn@ Oo o. . .
    \X/ snipabacken.se> O o .
    Jorgen Grahn, Nov 27, 2012
    #10
  11. Andre

    Les Cargill Guest

    Ian Collins wrote:
    > Les Cargill wrote:
    >> Andre wrote:
    >>> to organize source in a multi soucres project.
    >>> Is a main.h file with every definition for every sources the best or
    >>> a each.h file for each.c file the best.
    >>> It's a verry loooong time last I used c.
    >>> André

    >>
    >>
    >> There is no "best". Still:
    >>
    >> - Have one header .h per .c file.

    >
    > That isn't necessarily a good idea. If a header declares the interface
    > to a module or library, the functions declared in the header are often
    > defined in more than one C file.
    >



    But it's easier for me to use it to publish only stuff that's in
    one 'C' file. I realize people do this in other ways, but I've
    never found a case where this didn't work out...

    I have published libraries with *only* the constituent headers - an
    example is a signals processing library I wrote which laid over fftw-3
    and libsndfile. If you want the "fft" part, you include fft.h; reverse
    fft requires rfft.h

    A library is, after all, just an archive...

    > How to manage interface declarations and implementations really depends
    > on the the complexity of the application and the environment. In most
    > large projects I've seen or worked on there are a mix of public and
    > module private headers. OS libraries are a good example of this, there
    > will be a public header which ends up being part of the end user
    > distribution and private headers that never leave the private source tree.
    >


    For an O/S or compiler library, that's quite a different thing - if
    you're building under Unix path assumptions, then you are forced to
    at least have public headers.

    But IMO, everything in a ... non-infrastructure library
    should be public and on the same level. And this convention
    makes mixing 'C' and C++ much easier... plus it's much more grep-friendly.

    'Course, if you're backing into somebody else's arrangement,
    you are better off conforming...

    >> - Have all the #includes needed for that .c file #included in the .h
    >> file. That way, if there are 7 c files, "grep "#include" *.c | wc " will
    >> be 7.

    >
    > This practice often causes more trouble than it is worth.
    >
    >> - Have this basic structure:
    >>
    >> thing.h:
    >>
    >> #ifndef _THING_H_
    >> #define _THING_H_ 1

    >
    > The 1 is unusual and superfluous.
    >


    It's cheap :) Doesn't eat much.

    --
    Les Cargill
    Les Cargill, Nov 28, 2012
    #11
  12. Andre

    Les Cargill Guest

    Jorgen Grahn wrote:
    > On Tue, 2012-11-27, Ian Collins wrote:
    >> Les Cargill wrote:
    >>> Andre wrote:
    >>>> to organize source in a multi soucres project.
    >>>> Is a main.h file with every definition for every sources the best or
    >>>> a each.h file for each.c file the best.
    >>>> It's a verry loooong time last I used c.
    >>>> André
    >>>
    >>>
    >>> There is no "best". Still:
    >>>
    >>> - Have one header .h per .c file.

    >>
    >> That isn't necessarily a good idea. If a header declares the interface
    >> to a module or library, the functions declared in the header are often
    >> defined in more than one C file.

    >
    > I took it to be more of a rule of thumb.
    >



    That's the intention.

    >> How to manage interface declarations and implementations really depends
    >> on the the complexity of the application and the environment.

    > ...
    >
    >>> - Have all the #includes needed for that .c file #included in the .h
    >>> file. That way, if there are 7 c files, "grep "#include" *.c | wc " will
    >>> be 7.

    >>
    >> This practice often causes more trouble than it is worth.

    >
    > Yes -- that seems highly unusual and impractical. E.g. anyone who
    > wants to use the interface provided by foo.h will be poisoned by
    > everything needed to implement foo.c!
    >



    I've never found this to be a significant burden, but I do spend
    some time in trying to make interfaces as clean as possible.

    This was shop standard and was how some case tools did it, and
    I never bothered to go back to the old way.

    > Note that this is distinct from the idea of idempotent header files --
    > the idea that foo.h doesn't have a secret "shopping list" of other
    > header files which must be included first to make '#include "foo.h"'
    > compile.


    Yeah, I don't like that at all, and that's one reason I like having all
    foo.c 's dependencies explicit in foo.h.

    >
    > /Jorgen
    >


    --
    Les Cargill
    Les Cargill, Nov 28, 2012
    #12
  13. Andre

    Ian Collins Guest

    Les Cargill wrote:
    > Ian Collins wrote:
    >> Les Cargill wrote:
    >>>
    >>> There is no "best". Still:
    >>>
    >>> - Have one header .h per .c file.

    >>
    >> That isn't necessarily a good idea. If a header declares the interface
    >> to a module or library, the functions declared in the header are often
    >> defined in more than one C file.

    >
    > But it's easier for me to use it to publish only stuff that's in
    > one 'C' file. I realize people do this in other ways, but I've
    > never found a case where this didn't work out...


    Fair enough. I prefer more smaller C files over one bigger one, so my
    public headers tend to cover a group of files.

    > I have published libraries with *only* the constituent headers - an
    > example is a signals processing library I wrote which laid over fftw-3
    > and libsndfile. If you want the "fft" part, you include fft.h; reverse
    > fft requires rfft.h
    >
    > A library is, after all, just an archive...


    Take care with your terminology there, dynamic libraries are often
    different beasts from static archives.

    >> How to manage interface declarations and implementations really depends
    >> on the the complexity of the application and the environment. In most
    >> large projects I've seen or worked on there are a mix of public and
    >> module private headers. OS libraries are a good example of this, there
    >> will be a public header which ends up being part of the end user
    >> distribution and private headers that never leave the private source tree.
    >>

    >
    > For an O/S or compiler library, that's quite a different thing - if
    > you're building under Unix path assumptions, then you are forced to
    > at least have public headers.
    >
    > But IMO, everything in a ... non-infrastructure library
    > should be public and on the same level. And this convention
    > makes mixing 'C' and C++ much easier...


    I don't see why that would be the case. C++ happily uses system C
    libraries and there's nothing to stop you witting a library with a C
    interface entirely or partially in C++.

    > plus it's much more grep-friendly.


    find is your friend!

    > 'Course, if you're backing into somebody else's arrangement,
    > you are better off conforming...


    Yep.

    --
    Ian Collins
    Ian Collins, Nov 28, 2012
    #13
  14. Les Cargill <> writes:
    [...]
    > - Have this basic structure:
    >
    > thing.h:
    >
    > #ifndef _THING_H_
    > #define _THING_H_ 1
    > ...
    > #endif
    >
    > guarding all header files.

    [...]

    Identifiers starting with an underscore and an uppercase letter
    (or with two underscores) are reserved to the implementation for
    any use; in other words, you should never use such identifiers in
    your own code.

    Just use this:

    #ifndef THING_H
    #define THING_H
    ....
    #endif /* THING_H */

    (or some scheme that maps reasonably well from file names to
    identifiers without stepping on anything that's reserved).

    Note that identifiers starting with E and either a digit or an
    uppercase letter may be used for implementation-defined macros
    in <errno.h>, so a header name that happens to start with E might
    cause problems. One way to avoid that is:

    #ifndef H_THING
    #define H_THING
    ....
    #endif /* H_THING */

    It's not terribly likely that an implementation is going to use
    _THING_H_ or EXTRA_FOO for its own purposes, so you can very likely
    get away with using such identifiers yourself, but if you avoid
    reserved identifiers you have one less thing to worry about.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Will write code for food.
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
    Keith Thompson, Nov 28, 2012
    #14
  15. Andre

    Les Cargill Guest

    Ian Collins wrote:
    > Les Cargill wrote:
    >> Ian Collins wrote:
    >>> Les Cargill wrote:
    >>>>
    >>>> There is no "best". Still:
    >>>>
    >>>> - Have one header .h per .c file.
    >>>
    >>> That isn't necessarily a good idea. If a header declares the interface
    >>> to a module or library, the functions declared in the header are often
    >>> defined in more than one C file.

    >>
    >> But it's easier for me to use it to publish only stuff that's in
    >> one 'C' file. I realize people do this in other ways, but I've
    >> never found a case where this didn't work out...

    >
    > Fair enough. I prefer more smaller C files over one bigger one, so my
    > public headers tend to cover a group of files.
    >



    I too prefer smaller ones. Perhaps working with CASE tools that
    ended evolution in UML destroyed my good sense :), but that's
    how they roll - lots of small files, each with a minimum
    of side effects.

    In the example I gave, I don't think any of the source or
    header files were over 100 lines, blank lines and comments
    included.

    >> I have published libraries with *only* the constituent headers - an
    >> example is a signals processing library I wrote which laid over fftw-3
    >> and libsndfile. If you want the "fft" part, you include fft.h; reverse
    >> fft requires rfft.h
    >>
    >> A library is, after all, just an archive...

    >
    > Take care with your terminology there, dynamic libraries are often
    > different beasts from static archives.
    >


    I suppose... although I can easily think of a .so or .dll as
    nothing more than a fancier container... YMMV.

    >>> How to manage interface declarations and implementations really depends
    >>> on the the complexity of the application and the environment. In most
    >>> large projects I've seen or worked on there are a mix of public and
    >>> module private headers. OS libraries are a good example of this, there
    >>> will be a public header which ends up being part of the end user
    >>> distribution and private headers that never leave the private source
    >>> tree.
    >>>

    >>
    >> For an O/S or compiler library, that's quite a different thing - if
    >> you're building under Unix path assumptions, then you are forced to
    >> at least have public headers.
    >>
    >> But IMO, everything in a ... non-infrastructure library
    >> should be public and on the same level. And this convention
    >> makes mixing 'C' and C++ much easier...

    >
    > I don't see why that would be the case. C++ happily uses system C
    > libraries and there's nothing to stop you witting a library with a C
    > interface entirely or partially in C++.
    >


    I dunno - at least conceptually, it's simpler for me if I hold
    to a separately compiled module being roughly a "class", where the
    header is the "interface".

    You don't want to overdo it, of course.

    > > plus it's much more grep-friendly.

    >
    > find is your friend!
    >


    Couldn't agree more! But it's slightly better if you don't
    need to resort to it.

    >> 'Course, if you're backing into somebody else's arrangement,
    >> you are better off conforming...

    >
    > Yep.
    >


    --
    Les Cargill
    Les Cargill, Nov 28, 2012
    #15
  16. Andre

    Les Cargill Guest

    Keith Thompson wrote:
    > Les Cargill <> writes:
    > [...]
    >> - Have this basic structure:
    >>
    >> thing.h:
    >>
    >> #ifndef _THING_H_
    >> #define _THING_H_ 1
    >> ...
    >> #endif
    >>
    >> guarding all header files.

    > [...]
    >
    > Identifiers starting with an underscore and an uppercase letter
    > (or with two underscores) are reserved to the implementation for
    > any use; in other words, you should never use such identifiers in
    > your own code.
    >
    > Just use this:
    >
    > #ifndef THING_H
    > #define THING_H
    > ...
    > #endif /* THING_H */
    >
    > (or some scheme that maps reasonably well from file names to
    > identifiers without stepping on anything that's reserved).
    >



    Excellent point. I *always* forget that. Apologies for the noise;
    I simply meant "use guards on your header files."


    > Note that identifiers starting with E and either a digit or an
    > uppercase letter may be used for implementation-defined macros
    > in <errno.h>, so a header name that happens to start with E might
    > cause problems. One way to avoid that is:
    >
    > #ifndef H_THING
    > #define H_THING
    > ...
    > #endif /* H_THING */
    >
    > It's not terribly likely that an implementation is going to use
    > _THING_H_ or EXTRA_FOO for its own purposes, so you can very likely
    > get away with using such identifiers yourself, but if you avoid
    > reserved identifiers you have one less thing to worry about.
    >



    --
    Les Cargill
    Les Cargill, Nov 28, 2012
    #16
  17. Andre

    Ian Collins Guest

    Les Cargill wrote:
    >
    > I dunno - at least conceptually, it's simpler for me if I hold
    > to a separately compiled module being roughly a "class", where the
    > header is the "interface".


    Ah, I see a different in metaphor here.

    I would describe the collection of source files (typically in their own
    directory with a makefile) used to implement the interface declared in a
    header as a module. You appear to be describing an individual source
    file as a module.

    So if that's the case, we both have one header per module :)

    --
    Ian Collins
    Ian Collins, Nov 28, 2012
    #17
  18. Andre

    Les Cargill Guest

    Ian Collins wrote:
    > Les Cargill wrote:
    >>
    >> I dunno - at least conceptually, it's simpler for me if I hold
    >> to a separately compiled module being roughly a "class", where the
    >> header is the "interface".

    >
    > Ah, I see a different in metaphor here.
    >
    > I would describe the collection of source files (typically in their own
    > directory with a makefile) used to implement the interface declared in a
    > header as a module. You appear to be describing an individual source
    > file as a module.
    >
    > So if that's the case, we both have one header per module :)
    >



    Well, there ya go. :)

    --
    Les Cargill
    Les Cargill, Nov 28, 2012
    #18
  19. Ian Collins <> wrote:

    (snip)
    > Ah, I see a different in metaphor here.


    > I would describe the collection of source files (typically in their own
    > directory with a makefile) used to implement the interface declared in a
    > header as a module. You appear to be describing an individual source
    > file as a module.


    If you follow the source module goes to object module, and use
    one procedure/method per file, then it is more obvious with one
    source module per file.

    Many languages separately compile procedures in one file, but C doesn't.

    > So if that's the case, we both have one header per module :)


    -- glen
    glen herrmannsfeldt, Nov 28, 2012
    #19
  20. On Tuesday, November 27 2012, Les Cargill wrote:

    > Andre wrote:
    >> to organize source in a multi soucres project.
    >> Is a main.h file with every definition for every sources the best or
    >> a each.h file for each.c file the best.
    >> It's a verry loooong time last I used c.
    >> André

    >
    >
    > There is no "best". [...]


    Agreed.

    > - Have all the #includes needed for that .c file #included in the .h
    > file. That way, if there are 7 c files, "grep "#include" *.c | wc "
    > will
    > be 7.


    Not really sure I agree. I prefer having my #includes in the .c,
    because I believe the header file, if it needs to be included by other
    ..c files, must not interfere much with them, i.e., they shouldn't carry
    other (possible obscure) header files that won't be needed for the .c
    file(s).

    But as you said, it's all IMO. You suggestion still seems sensible to
    me, much better than something I've read some days ago: "Why complicate?
    Create one big .h file which #includes *everything* your project needs,
    and then just #include it on the top of every .c file of your project".
    Heh...

    --
    Sergio
    Sergio Durigan Junior, Nov 28, 2012
    #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. Stan
    Replies:
    3
    Views:
    457
    Brock Allen
    May 5, 2005
  2. Diego Martins
    Replies:
    5
    Views:
    5,246
    Diego Martins
    Jun 19, 2007
  3. Kevin
    Replies:
    16
    Views:
    47,233
    Roedy Green
    Jan 30, 2008
  4. Eddy Xu
    Replies:
    5
    Views:
    111
    Eddy Xu
    Apr 11, 2008
  5. oldyork90
    Replies:
    1
    Views:
    150
    Jeremy J Starcher
    Sep 10, 2008
Loading...

Share This Page