Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!uflorida!haven!mimsy!chris From: chris@mimsy.UUCP (Chris Torek) Newsgroups: comp.lang.c Subject: Re: TLINK errors (cc/lint were clean) Message-ID: <15819@mimsy.UUCP> Date: 6 Feb 89 04:07:00 GMT References: <44100021@hcx1> <508@jhereg.Jhereg.MN.ORG> Organization: U of Maryland, Dept. of Computer Science, Coll. Pk., MD 20742 Lines: 53 [re def/ref vs common, where the `extern' in foo.c: int a; bar.c: /* extern */ int a; matters] In article <508@jhereg.Jhereg.MN.ORG> mark@jhereg.Jhereg.MN.ORG (Mark H. Colburn) writes: >The fact the your unix compiler/linker does not catch this error is >actually just sloppy play on your compiler vendors part. Multiple >declarations of this sort usually indicate a bug in the program somehere. Hardly. The Unix compilers and linkers use the `common model', in which a declaration without `extern' and without an initial value compiles to a FORTRAN-common-style definition, such as .comm _a,4 for int a; (the 4 here is the size of `a' in bytes). Other compilers use the more restrictive `def/ref model': _a: .long 0 for `int a' (and `int a = 0') and .extern _a for `extern int a'. The def/ref model *can* catch bugs like this one: foo.c: int status; bar.c: struct { char *msg; int code; } status; but I prefer the common model. Lint catches the above bug, and the def/ref compiler does *not* catch the bug if one writes instead foo.c: int status; bar.c: extern struct { char *msg; int code; } status; or (if extern declarations carry size information but sizeof(int)==sizeof(char *)) foo.c: int status; bar.c: extern char *status; so one must run lint anyway. -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163) Domain: chris@mimsy.umd.edu Path: uunet!mimsy!chris