I'm writing a program with a lot of .c files, each with its own
corresponding .h file. It has a Makefile that handles the compilation.
I've never written such a large program before and, in fact, it wasn't
very long ago that I was routinely defeated by dealing with pointers and
debugging anything and my former efforts at top down approaches were
defeated
by my complete lack of competence at actually designing the data
structures,
writing routines to handle them and C programming in general. But recently
I seem to have gotten better since then and so far it has been going ok,
albeit from a bottom up approach. Next time I try something like this,
I'll
take more of a top down approach, since I'll be a little better at C and
at
debugging, and will have a better idea of how things work and what to
expect,
but this program kind of grew a little bit at a time and will later shrink
when I discard parts that seemed like a good idea at the time but really
weren't.
The way the program was recently constituted, each of the .c files
contained
the line, #include "main.h", and the file main.h had an #include for all
the
other .h files, as well as stuff like <stdio.h>. Each .h file contained
(in principle) an external declaration of each routine defined in the
corresponding .c file. Sometimes I would get complaints from the compiler
that I was able to fix by changing the order in which the header files
were
included. This worked well enough for me to put the program to some rather
severe tests, which it passed. On the other hand, I still had to fix a lot
of
bugs that ultimately turned out to be caused by calling functions with the
wrong number of arguments. I used prototypes in the .c files (except that
when I used a function as an argument I usually omitted its full
prototype),
while in the .h files the external declarations showed no arguments.
Apparently that was the reason the compiler wasn't catching errors of the
wrong number of arguments when routines were called from other files. I
decided to try to get the compiler (gcc) to check for everything it could
possibly check for and, on advice, used the following:
-Wtraditional -Wshadow -Wpointer-arith -Wbad-function-cast
-Wcast-qual -Wcast-align -Wwrite-strings -Wconversion
-Waggregate-return -Wstrict-prototypes -Wmissing-prototypes
-Wmissing-declarations -Wredundant-decls -Wnested-externs
as well as -g, of course. Then I went through the all the header files
and the corresponding .c files and replaced the old external declarations
by copies of the actual declarations in the .c files, followed by ;,
and also made sure that all functions called as arguments also had
full prototypes. Since then I've been dealing with some thousands of
complaints from the compiler. I managed to reduce the number to several
hundred by commenting out some external declarations, modifying
declarations
such as
char * namelist[20] = {"larry","moe","curley",...};
by
char namelist[20][10] = {"larry","moe","curley",...};
changing the order of header files, renaming variables that happened to
have
the same names as enum type components and other global variables,
deleting
duplicate #include lines in main.h (such as two occurrences of
#include "garbage.h" that I hadn't noticed because I'd found it necessary
to
violate alphabetical order of the header files in order to deal with
compiler
complaints) but the complaints about redundant declarations and the
complaints
about structures being declared inside of function prototypes were
unrelenting.
I decided to deal with this problem in the following way: I went through
all
the .c files and replaced the #include "main.h" by an inclusion of the .h
file corresponding to the .c file. That still caused thousands of lines of
complaints. So, to simplify the problem I decided to just try to compile
one .c file at a time. For example, when compilation of foo.c indicated
that another header file was needed, it was also #included, and when the
ordering of the growing list of header files, included in the .c file, was
causing a problem, I changed the order, and it eventually compiled with
gcc -c foo.c and produced foo.o. I think that I'm now on the right track
and
that this divide and conquer approach will work better than the unwieldy
approach of, in effect, finding one header file that all the .c files
could include. On the other hand, I don't KNOW that I'm on the right
track,
so I thought it would be a good idea to ask about it here.
Also, a more fundamental problem that may be revealed by this is that
I haven't correctly dealt with the problem of what routines to put in
what .c files. Sometimes I tried to group routines according to the data
types they were most involved with, but sometimes routines involve two or
more
data types. Sometimes routines were grouped according to the kind of
action they take, e.g. allocation routines in alloc.c and copying routines
in copy.c, but sometimes copying involves allocation and sometimes
allocation
involves copying, so there are calls between the two .c files in both
directions. So, I think I need to know more about how to decide what
routines
to put in what files and how to be more systematic about making such
decisions.
Maybe that is all implicit in a top down approach. I'd be glad to read
something that is more explicit about how a top down approach deals with
the distribution of routines in files.
There is no reason why I can't, in principle, incor****ate whatever I learn
about it in the next major revision of the program. I plan eventually to
rewrite the entire program as a literate do***ent using CWEB, which I hope
will make it easier for me to maintain, and which will also hopefully
eliminate all of the problems I'm presently having with header files and
priority of declarations. But first I want to get the program working the
way I want it to work since, at my present level of competence, I need to
be reassured that it will eventually get to that point.
--
Ignorantly,
Allan Adler <ara@[EMAIL PROTECTED]
>
* Disclaimer: I am a guest and *not* a member of the MIT CSAIL. My actions
and
* comments do not reflect in any way on MIT. Also, I am nowhere near
Boston.
--
comp.lang.c.moderated - moderation address: clcm@[EMAIL PROTECTED]
-- you must
have an appropriate newsgroups line in your header for your mail to be
seen,
or the newsgroup name in square brackets in the subject line. Sorry.


|