gwu@nujoizey.tcs.com (George Wu) (04/09/91)
Consider the following post-preprocessed files:
file1.c:
class AAAA { . . . };
class BBBB { . . . };
int func(AAAA *p1) { . . . }
file2.c:
class BBBB { . . . };
class AAAA { . . . };
extern int func(AAAA *p1);
int main(int argc, char *argv[])
{
func(NULL);
}
When the compiler mangles func(), it will refer to the type of p1 and
p2 by some abbreviation. In file1.c, it will, say, rename AAAA to $0 and
BBBB to $1. In file2.c, it will see the declaration of BBBB first, and use
$0 for it, and $1 for AAAA. When attempting to link these two files, one
gets an undefined symbol because func() has mangled to different symbols in
each file.
Hence, due to name mangling, the order of class declarations is very
significant. Depending upon the implementor involved, we take one of two
approaches. One project has a single header file, internal.h, which
includes nearly every other header file in the system. All implementation
files include internal.h, hence they all have the same order of class
declaration. The second approach is for each header file to explicitly
include all necessary header files containing classes to which it refers.
For instance, if C.h includes a reference to class A, it includes A.h.
While this approach has worked so far, I'm not convinced it is completely
sound. There may be more than one "dependency tree," and the order could
then be reversed accidentally.
Anyways, has anyone else thought of a better solution or improvement
on these two methods? I personally find them both to be hacks.
George
PS: One reason for one implementor choosing the first approach was the Sun
cpp bug which caused a core dump when the total number of #include's in a
single include tree exceeded some table size. IMHO, the better solution is
to use a better cpp (GNU cpp).
----
George J Wu, Software Engineer | gwu@tcs.com or uunet!tcs!gwu
Teknekron Communications Systems, Inc.| (415) 649-3752
2121 Allston Way, Berkeley, CA, 94704 | Quit reading news. Get back to work.