|
|
General-purpose components typically provide more functionality than a single application needs. Take the String(C++) component, for example. It provides more than 100 functions you can use on Strings. A programmer whose application needs only ten of these will be unlikely to use the String component if all 100 functions must be linked with the application.
Similarly, if a component X is implemented using component Y, then programmers will be reluctant to use component X if the executable includes not only all of X, but all of Y as well.
We used two techniques to minimize linkage dependencies. The first of these is illustrated by the String component. We broke down the 100 String functions into 24 clusters of functions that are likely to be used together and implemented the functions of each cluster in a single .c file. We did not place each function in a separate .c file because of problems this creates for some linkers.
When an application uses just a few String functions, it is therefore likely that just a few String object files will be included in the application's executable. Similarly, if component X is implemented using component Y, it is likely that just a few Y files will be linked in (namely, those required by the object files in component X).
The second technique we used to minimize linkage dependencies was to restrain ourselves from implementing component X in terms of component Y except when component X uses a substantial subset of component Y's facilities. If X uses only a small subset of Y's facilities, we prefer to implement in X the needed facilities from scratch.
A particular (but not the only) instance of our effort to minimize linkage dependencies in the library is the following guarantee:
Client programs which do not themselves use iostreams will not have any part of the iostream library linked into their application.
Linking iostreams into programs which do not themselves use it is unacceptable to many of our clients.