lvc@tut.cis.ohio-state.edu (Lawrence V. Cipriani) (12/16/87)
About 5 years ago at the beginning of a major porting effort (thousands of files, and millions of lines of code) I had this bright idea for making #includes harmless with the: #ifndef SPLAT_H #define SPLAT_H ... #endif /* SPLAT_H */ syntax. The idea was to make each header file self sufficient. If /usr/include/local/abc.h needed the information in /usr/include/local/def.h, then abc.h would have the cpp statement #include <local/def.h> and all the c code would have to do is have the cpp statement: #include <local/abc.h> and it would get everything it needed. After using this for about 5 years I now believe this was one of the worse ideas I ever had. The advantage is that it is great in development (a relatively short time) (except for the slower compilation times - yes you can notice it), but after that you have the maintenance and enhancement stage (a relatively long time). It is there where the idea fails miserably. Instead of looking in the c file for all the includes, you have to check all of the includes for includes (and recursively) till you find what you want. A partial remedy to this is to generate a cross reference every night. If the header files provided with your system are changed, then you loose portability, and reusability. Makefile dependency lists have files you might not care about, and really do not affect your program. Two related products that reused our code have ripped out all of this and converted their c programs to explicitly list all the header files it needs. If I had to do it over again I wouldn't do this. Maybe this isn't convincing you, but I'm convinced it's a lousy idea. -- Larry Cipriani AT&T Network Systems at cbosgd!osu-cis!tut!lvc Ohio State University
gwyn@brl-smoke.ARPA (Doug Gwyn ) (12/17/87)
In article <3251@tut.cis.ohio-state.edu> lvc@tut.cis.ohio-state.edu (Lawrence V. Cipriani) writes: >Two related products that reused our code have ripped out >all of this and converted their c programs to explicitly >list all the header files it needs. > >If I had to do it over again I wouldn't do this. Maybe this isn't >convincing you, but I'm convinced it's a lousy idea. I've tried it both ways, and they both have advantages and drawbacks. The main objections to having the application programmer explicitly include all the prerequisites are: 1) It's sometimes hard to get them in the right order. 2) If a header acquires a new dependency, all the applications may potentially have to be modified. 3) Documenting header interdependencies is a drag. The main extra thing one needs to do to make the header-includes-all- preresuisite-headers approach work slickly is to give each header its own name space. On a large current project we're doing just that, by assigning a unique 2-letter "package prefix" for all visible symbols that each header declares/defines. This approach has been working well so far.
peter@sugar.UUCP (Peter da Silva) (12/20/87)
lvc@tut.cis.ohio-state.edu (Lawrence V. Cipriani) writes: > #ifndef SPLAT_H > #define SPLAT_H > ... > #endif /* SPLAT_H */ > > After using this for > about 5 years I now believe this was one of the worse ideas I > ever had. The advantage is that it is great in development > (a relatively short time) (except for the slower compilation > times - yes you can notice it), but after that you have the > maintenance and enhancement stage (a relatively long time). > It is there where the idea fails miserably. It's great for system include files (which you (hopefully) won't be hacking on). You can get rid of the speed problem like so: #ifndef INTUITION_INTUITION_H #define INTUITION_INTUITION_H TRUE #ifndef EXEC_TYPES_H #include "exec/types.h" #endif #ifndef GRAPHICS_GFX_H #include "graphics/gfx.h" #endif #ifndef GRAPHICS_CLIP_H #include "graphics/clip.h" #endif ... and so on... #endif /* INTUITION_INTUITION_H */ -- -- Peter da Silva `-_-' ...!hoptoad!academ!uhnix1!sugar!peter -- Disclaimer: These U aren't mere opinions... these are *values*.