Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!wasatch!cmos.utah.edu!jacobs From: jacobs%cmos.utah.edu@wasatch.UUCP (Steven R. Jacobs) Newsgroups: comp.lang.c Subject: Re: Question about linking files Message-ID: <1439@wasatch.UUCP> Date: 26 Mar 89 13:49:56 GMT References: <18925@iuvax.cs.indiana.edu> <16541@mimsy.UUCP> Sender: news@wasatch.UUCP Reply-To: jacobs%cmos.utah.edu.UUCP@wasatch.UUCP (Steven R. Jacobs) Organization: University of Utah, Computer Science Dept. Lines: 58 In article <16541@mimsy.UUCP> chris@mimsy.UUCP (Chris Torek) writes: >In article <18925@iuvax.cs.indiana.edu> bobmon@iuvax.cs.indiana.edu >(RAMontante) writes: >>... a couple of people are saying that this isn't (TurobC/MSC/whoever)'s >>fault, because C requires that all routines (all symbols, maybe?) in a >>file be linked in if any of them are. > >Given that the pANS does not have the concept of a `library', or >even of `separate compilation', this is clearly false. It is, however, >difficult to tell which of several code and/or data sections may >be required. Consider, for instance, the following: > > static void a(), b(); > static void (*table)[2] = { a, b }; > > entry_point(int n) { go(&table[0], n); } > > static void go(void (**tab)(), int n) { > (*tab[n])(); /* this calls either a() or b() */ > } > > static void a() { (void) printf("a called\n"); } > static void b() { (void) printf("b called\n"); } > >It is not possible to tell, at compile time, which of `a' and `b' will >be called. If `n' is deleted from entry_point(), and we call `go' with >0, b() can be elided. Discovering this is quite difficult. Yes, but suppose the following (common) situation occurs: extern void a(), b(), c(), d(); /* NOTE no longer static */ static void (*table)[2] = { a, b }; /* c() and d() not used here */ /* extra lines omitted */ and in a different file: void a() { (void) printf("a called\n"); } void b() { (void) printf("b called\n"); } void c() { (void) printf("c called\n"); } void c() { (void) printf("d called\n"); } This situation must not be too hard to detect, since lint will give "function defined but not used" messages in this case. Admittedly, this might not be an appropriate thing for the linker to handle, but it would sure be nice if the librarian would detect such cases and treat them as if they were compiled from separate files, at least when no variables of "file-only" scope are involved. Static functions that are not used could be completely eliminated, and library functions that are similar could be conveniently grouped into a single source file. I find it easier to manage libraries of 20,000 lines of code when they are in a few dozen files of a few hundred lines each as opposed to hundreds of files, many of which contain similar functions that are only 5 to 10 lines of code. The limitations of present linkers/librarians force my programs to be larger than they need to be, or force me to deal with hundreds of source files. Steve Jacobs ({ihnp4,decvax}!utah-cs!jacobs, jacobs@cs.utah.edu)