[comp.unix.questions] header file duplicate definitions advice sought

cracraft@pogo.ai.mit.edu (Stuart Cracraft) (03/08/91)

Hello!

I am wondering if someone can help me with a problem I'm trying to resolve.

How can you eliminate redefined errors in C when you have several thousand 
"#define"'s defined in both *.h and *.c files(about 2000 files combined)?

Where *.h and *.c files are scattered around in different directories.

So far I have only collected very few possible ideas to the problem.
One of them is to have "#ifndef" statements over places that I am getting
redefined errors.  However, this is not a good solution because this
will not work on case such as below:

==========================================================================
inside abc.h                          inside def.h
#define a 4                           #define a 5
                 inside ghi.c
		 #include <abc.h>
		 #include <def.h>

            Which value is ghi.c referring to, 4 or 5?
Thus, I would end up searching in ghi.c to see which is a appropriate value
and I might have to do this million times manually for other similar cases.

Another idea is to list all the redefined symbols(using a script to 
retrieve) in following ways:

                    header file      
                     symbol is		
symbol    value       located		files including header files
------    -----     -----------         ----------------------------
a           5        abc.h                def.h
					  xyz.h
					  kuy.c
a	    3	     kby.h		  ubc.h
					  ppp.h

        etc...

This gives me more of general info which I might use it in changing the
symbol name in the header file and also in files where header file
is included.  And I think this is a very clean solution except that
again there are too many symbols(approximately 7000 of them) and I 
would end up spending million years.

I have couple more ideas like above but they are not a good approach.
Actually, I don't think there are any good simple way of resolving 
the problem but I am asking if anyone out there has/had similar 
experience to share with me how you have dealt with the problem.

Thank you (sorry my question got little too lengthy :)

adrianho@barkley.watt.berkeley.edu (Adrian J Ho) (03/08/91)

In article <CRACRAFT.91Mar7214134@pogo.ai.mit.edu> cracraft@pogo.ai.mit.edu (Stuart Cracraft) writes:

>How can you eliminate redefined errors in C when you have several thousand 
>"#define"'s defined in both *.h and *.c files(about 2000 files combined)?

The short answer: Adopt sound programming practices (ie. be neat and tidy).

Suggestions:
1) Where possible, place #define's ONLY in *.h -- there's no real
reason for #define's in *.c.
2) Have a corresponding .h for each .c which needs #defines -- don't
try lumping all your #define's in a single .h (unless there are only a
few of them).
3) To solve the problem of multiple #include's, take a hint from the
system include files:

	inside foo.h:
	#ifndef _foo_h_
	#define _foo_h_
	<declarations, #define's, etc.>
	#endif /* _foo_h_ */

Remember, all that stuff has to go into the *includee*, NOT in the
*includer*.  (That's a common mistake among people who're advancing up
the C ladder and want to use this technique.)

>==========================================================================
>inside abc.h                          inside def.h
>#define a 4                           #define a 5
>		    inside ghi.c
>		    #include <abc.h>
>		    #include <def.h>
>
>	       Which value is ghi.c referring to, 4 or 5?

ACK!!!  Whoever wrote that should be locked away for a long time with a
copy of K&P's "Elements of Programming Style"!!  8-)

Seriously though:
4) Use meaningful names for macros, and stick to some method to
distinguish macros from procedures (I *CAPITALIZE* all my #define's).
Otherwise, you're likely to end up with:

main()
{
	int 5;		/* was "int a" */
}

when cpp's through.

>Thus, I would end up searching in ghi.c to see which is a appropriate value
>and I might have to do this million times manually for other similar cases.

Ah, so you're trying to reorganize someone else's code, am I right?

>Another idea is to list all the redefined symbols(using a script to 
>retrieve) in following ways:
[ example deleted ]
>This gives me more of general info which I might use it in changing the
>symbol name in the header file and also in files where header file
>is included.  And I think this is a very clean solution except that
>again there are too many symbols(approximately 7000 of them) and I 
>would end up spending million years.

Frankly, if we're talking about 20,000 lines of this kind of code, I'm
surprised it worked at all!!  I'd suggest throwing it back in the
author's face and getting him to tidy it up himself. if that is an
option.  If not, good luck -- you've got a long day ahead of you.

>I have couple more ideas like above but they are not a good approach.
>Actually, I don't think there are any good simple way of resolving 
>the problem but I am asking if anyone out there has/had similar 
>experience to share with me how you have dealt with the problem.

If you need to maintain this type of code, it'll be a painstaking
process to replace all the macros with better ones, but you'll win in
the long run.  When I run across such code, I usually take drastic
measures: I trash the code and write my own.  (Takes less time on the
whole, and hey, I'll probably learn something new along the way!)

Oh, one more thing: Code like that usually indicates that the
programmer hadn't bothered to sit down and:

5) PLAN ALL YOUR PROJECTS (no matter what size).

Skip that step with a 2000-file project and I'll betcha 10 to 1 you'll
hafta start from scratch.
--
-----------------------------------------------------------------------------
Adrian Ho, EECS (pronounced "eeks!") Dept.		Phone: (415) 642-5563
UC Berkeley					adrianho@barkley.berkeley.edu
Domain: sesame-street (telly,bigbird,snuffy,oscar,kermit,bert,grover,barkley)
Favorite expression: "There's no business like monkey business."

mike (03/09/91)

In an article, pogo.ai.mit.edu!cracraft (Stuart Cracraft) writes:
>How can you eliminate redefined errors in C when you have several thousand 
>"#define"'s defined in both *.h and *.c files(about 2000 files combined)?

I do it rather easily; with multiple headers, you simply do something
like this:

#ifndef _H_myhead
#define _H_myhead
	.
	. (defines and other Good Stuff go here)
	.
#endif

You do this for each header file.  Works like a charm for me.
-- 
Michael Stefanik, MGI Inc., Los Angeles| Opinions stated are not even my own.
Title of the week: Systems Engineer    | UUCP: ...!uunet!bria!mike
-------------------------------------------------------------------------------
Remember folks: If you can't flame MS-DOS, then what _can_ you flame?

gwyn@smoke.brl.mil (Doug Gwyn) (03/11/91)

In article <CRACRAFT.91Mar7214134@pogo.ai.mit.edu> cracraft@pogo.ai.mit.edu (Stuart Cracraft) writes:
>How can you eliminate redefined errors in C when you have several thousand 
>"#define"'s defined in both *.h and *.c files(about 2000 files combined)?

(This is more appropriate for comp.lang.c.)

The basic problem you have is that C supports only a few "flat" name
spaces.  Thus, if one wishes to properly package related sets of
identifiers without conflict among multiple packages, one has to
devise his own packaging scheme.  For BRL's MUVES project we reserved
the first two characters of "visible" (extern, macro, and file)
identifiers to denote the specific package, and maintained a central
registry of package names.  Of course each package had a header that
defined its visible interface.

There is NO satisfactory way to handle a situation such as you
describe, where insufficient care was taken in designing the interfaces.