what is the best way

A

Andre

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é
 
B

Ben Bacarisse

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

Malcolm McLean

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

James Kuyper

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

Les Cargill

Andre said:
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.
 
I

Ian Collins

James said:
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?
 
I

Ian Collins

Les said:
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.
 
J

James Kuyper

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?
 
I

Ian Collins

James said:
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 :)
 
J

Jorgen Grahn

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


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
 
L

Les Cargill

Ian said:
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...
This practice often causes more trouble than it is worth.


The 1 is unusual and superfluous.

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

Les Cargill

Jorgen said:
I took it to be more of a rule of thumb.


That's the intention.
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.
 
I

Ian Collins

Les said:
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.
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.
 
K

Keith Thompson

Les Cargill said:
- 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.
 
L

Les Cargill

Ian said:
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.
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.
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.
find is your friend!

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

Les Cargill

Keith said:
Les Cargill said:
- 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."
 
I

Ian Collins

Les said:
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 :)
 
L

Les Cargill

Ian said:
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. :)
 
G

glen herrmannsfeldt

(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
 
S

Sergio Durigan Junior

Andre said:
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...
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,969
Messages
2,570,161
Members
46,710
Latest member
bernietqt

Latest Threads

Top