guthriew@arcturus.uucp (Guthrie;Wade) (06/08/91)
I have this quandry regarding include files in a large (I mean *REALLY* large) software system. The software team with which I am working is developing a few hundred thousand line project which is broken up into several...let's call them "chunks". The chunks communicate with each other by passing (message-specific) packets which are described by 'C' structures. The problem we face is managing the include files for the interface structures. We have around 15 chunks each of which must interface with several other chuncks (many of the chunks are things like utilities, BIT, database, stuff like that). Beyond this, the software must interface with the operating system to deal with system resources, semiphores, inter-process queues, etc. In order to follow the guidelines of 1) no nested include files and 2) limiting the scope of globals and typedefs, we have come up with an abysmally complex array of include files. We have essentially two include files for each pair of chunks (e.g., BIT-to-database and database-to-BIT interface definitions), an array of include files for constants, and another array for system resources. A further problem arises when, for example, the "utilities" chunk has a common output format between itself and both BIT and database. My question is this: How do other projects deal with this problem? What is used to partition the include files to try to keep the list of files small and at the same time limit the exposure of information (global data and type definitions) to chunks that do not use that information? I am particularly interested in solutions used for big projects (e.g., BSD). Thank you ever so much in advance. -- Wade Guthrie (evil@arcturus.UUCP) | "The likelihood of one individual being ...uunet!ccicpg!felix!arcturus!evil | right increases with direct proportion to Rockwell International; Anaheim, CA | the intensity with which others are trying My opinions, not my employer's. | to prove him wrong", Mr. Jordan
bxw@ccadfa.adfa.oz.au (Brad Willcott) (06/08/91)
Your problem seems to me to be simple of solution. That is unless I misread your article. Why don't you use preprocessor defines in your source files, and test for them in your include files. Here is an example: ---------- source.c --------- #define BIT_to_DBMS #include <header.h> ... ----------------------------- ---------- major.c ---------- #define SYSTEM_ACCESS #include <header.h> ... ----------------------------- --------- header.h ---------- #ifdef BIT_to_DBMS ... #endif /* BIT_to_DBMS */ #ifdef SYSTEM_ACCESS ... #endif /* SYSTEM_ACCESS */ #ifdef DBMS_to_BIT ... #endif /* DBMS_to_BIT */ ----------------------------- If this is NOT a solution to your problem, then I DON'T understand it. -- Brad Willcott, ACSnet: bxw@ccadfa.cc.adfa.oz Computing Services, Internet: bxw@ccadfa.cc.adfa.oz.au Australian Defence Force Academy, UUCP:!uunet!munnari.oz.au!ccadfa.oz!bxw Northcott Dr. Campbell ACT Australia 2600 +61 6 268 8584 +61 6 268 8150 (Fax)
stachour@sctc.com (Paul Stachour) (06/10/91)
guthriew@arcturus.uucp (Guthrie;Wade) writes: > ...(stuff) >In order to follow the guidelines of > 1) no nested include files and > 2) limiting the scope of globals and typedefs, > ...(more stuff) We have found the guideline of no nested include files too restricting, as well as (my opinion) silly. Anytime you use a service-routine, you should not have to see how that service routine works. But if your access to a service routine depends (as it should) on the data-structures defined by that sevice routine (such as a structure containing a complex number) that you don't use, but that the set-of-service routines do, YOU SHOULD NOT BE REQUIRED TO INCLUDE THE DEFN OF COMPLEX NUMBERS And this principle applies though many levels of nesting. We use the "protected" method to prevent the secondary problem in C of including a file more than once. It's not a big thing, just a slight increase in procrocessor time. Of course the way to work is to be in a language with real modules, such as Ada, Euclid, or Modula2, but I suspect that is not likely in your environment. Good Luck! ..Paul (SCTC) -- Paul Stachour SCTC, 1210 W. County Rd E, Suite 100 stachour@sctc.com Arden Hills, MN 55112 [1]-(612) 482-7467
koerber.sin@sni.de (Mathias Koerber) (06/11/91)
In article <1991Jun7.233854.11170@arcturus.uucp> guthriew@arcturus.uucp (Guthrie;Wade) writes: > >In order to follow the guidelines of > > 1) no nested include files and > 2) limiting the scope of globals and typedefs, Why no nested include files? They are a *GOOD THING*, especially when one include file automatically includes the definitions it references itself. On pre-ansi compiler you must be a bit carefule about multiple inclusions though, since not all headers have the #ifndef THIS_IS_A_UNIQUE_DEFINE #define THIS_IS_A_UNIQUE_DEFINE ... #endif code to skip the file when it was already included. Maybe you could add them to your standard header files to make it even easier on the programmer. Just be sure to pick unique_defines that are guaranteed to be really unique. Mathias
chaplin@keinstr.uucp (chaplin) (06/21/91)
In article <1966@nixsin.UUCP> koerber.sin@sni.de writes: >In article <1991Jun7.233854.11170@arcturus.uucp> guthriew@arcturus.uucp (Guthrie;Wade) writes: >> >>In order to follow the guidelines of >> >> 1) no nested include files and >> 2) limiting the scope of globals and typedefs, > >Why no nested include files? They are a *GOOD THING*, especially when one >include file automatically includes the definitions it references itself. On >pre-ansi compiler you must be a bit carefule about multiple inclusions though, >since not all headers have the > >#ifndef THIS_IS_A_UNIQUE_DEFINE >#define THIS_IS_A_UNIQUE_DEFINE >... >#endif > >code to skip the file when it was already included. Maybe you could add them >to your standard header files to make it even easier on the programmer. Just >be sure to pick unique_defines that are guaranteed to be really unique. > >Mathias One technique I have used to make the defines unique is to use the name of the header file. Eg, in my header file foobar.h you will find: #ifndef FOOBAR_H #define FOOBAR_H ... #endif -- Roger Chaplin / Instruments Division Engineering / "Though I'd been lost now I chaplin@keinstr.uucp / CI$: 76307,3506 / felt I was found when He #include <disclaimer.h> / looked at me with His #include "disclaimer.h" /* cover all bases */ / forgiving eyes." - Michael Card
mouse@thunder.mcrcim.mcgill.edu (der Mouse) (06/26/91)
In article <1991Jun20.170144.1109@keinstr.uucp>, chaplin@keinstr.uucp (chaplin) writes: > One technique I have used to make the defines unique is to use the > name of the header file. Eg, in my header file foobar.h you will > find: > #ifndef FOOBAR_H > #define FOOBAR_H > ... > #endif I used to do that too, until I found I had two time.h files, both using TIME_H. So now I tack on a 32-bit hash of the file contents (computed by wraphfile, the program that throws the construct around the file in the first place). Now the time.hs use different defines. der Mouse old: mcgill-vision!mouse new: mouse@larry.mcrcim.mcgill.edu
darcy@druid.uucp (D'Arcy J.M. Cain) (06/27/91)
In article <1991Jun26.091408.5023@thunder.mcrcim.mcgill.edu> der Mouse writes: >> #ifndef FOOBAR_H >> #define FOOBAR_H >> ... >> #endif >I used to do that too, until I found I had two time.h files, both using >TIME_H. So now I tack on a 32-bit hash of the file contents (computed Why go through that? I assume you mean that you have something like time.h and sys/time.h so just prepend _SYS_ to the defines in the sys directory: #ifndef _SYS_TIME_H #define _SYS_TIME_H etc. -- D'Arcy J.M. Cain (darcy@druid) | D'Arcy Cain Consulting | There's no government Toronto, Ontario, Canada | like no government! +1 416 424 2871 |
bhoughto@bishop.intel.com (Blair P. Houghton) (06/27/91)
In article <1991Jun26.213114.236@druid.uucp> darcy@druid.uucp (D'Arcy J.M. Cain) writes: >Why go through that? I assume you mean that you have something like time.h >and sys/time.h so just prepend _SYS_ to the defines in the sys directory: Anyone know a system where one's not just a {link,symlink} to the other? What is the difference? --Blair "Fore!"
brnstnd@kramden.acf.nyu.edu (Dan Bernstein) (06/28/91)
In article <4896@inews.intel.com> bhoughto@bishop.intel.com (Blair P. Houghton) writes: > In article <1991Jun26.213114.236@druid.uucp> darcy@druid.uucp (D'Arcy J.M. Cain) writes: > >Why go through that? I assume you mean that you have something like time.h > >and sys/time.h so just prepend _SYS_ to the defines in the sys directory: > Anyone know a system where one's not just a {link,symlink} to the other? Yep: a perfectly-standard-except-all-those-little-porting-bugs BSD 4.3 system. > What is the difference? They're not just different. They're incompatible. They end up defining struct tm in two different ways; the people who ported the system to this hardware managed to copy the definition from somewhere else to <sys/time.h>. As another example, our BSD 4.3+NFS Mt. XINU system has struct tm in <time.h>. <sys/time.h> has various timefoo definitions for various foo, then #ifndef KERNEL #include <time.h> #endif. In any case, there are lots of other examples of include files where you want to prepend the directory name instead of assuming a flat namespace. ---Dan
mouse@thunder.mcrcim.mcgill.edu (der Mouse) (06/29/91)
In article <1991Jun26.213114.236@druid.uucp>, darcy@druid.uucp (D'Arcy J.M. Cain) writes: > In article <1991Jun26.091408.5023@thunder.mcrcim.mcgill.edu> der Mouse writes: >>> #ifndef FOOBAR_H >>> #define FOOBAR_H >>> ... >>> #endif >> I used to do that too, until I found I had two time.h files, both >> using TIME_H. So now I tack on a 32-bit hash of the file contents > Why go through that? I assume you mean that you have something like > time.h and sys/time.h so just prepend _SYS_ to the defines in the sys > directory: > #ifndef _SYS_TIME_H > #define _SYS_TIME_H Because there's no end to that. Should I prepend _USR_INCLUDE_SYS_TIME_H? Or perhaps just _INCLUDE_SYS_TIME_H? Why should some of the leading directories be included but not the rest? And I can't just strip off /usr/include, because the same scheme is used for include files elsewhere. Perhaps I should do _SYS_TIME_H and then _THUNDER_HOME_SHAMASH_MOUSE_SUN4_INCLUDE_HTABLE_H for the htable.h in my own include directory? Ideally, the protection would protect against any inclusion of the same file multiple times. But there's no simple way to ensure that. I suppose I could take the entire contents of the file, somehow process it (reversibly) into a unique string that's a legal cpp symbol, and use that. But that triples the size of the file and will break some cpps and stress the rest. der Mouse old: mcgill-vision!mouse new: mouse@larry.mcrcim.mcgill.edu