hascall@atanasoff.cs.iastate.edu (John Hascall) (11/16/89)
I have been involved in a ``discussion'' over which (if any) of the four following pairs of modules are identical in result. Assume that in each case the two modules are compiled separately and linked with: int main(int argc, char **argv) { void foo(void); void bar(void); foo(); bar(); return(1); } module1.c module2.c ------------------- ------------------- (a) int i; int i; void foo(void) {} void bar(void) {} (b) extern int i; int i; void foo(void) {} void bar(void) {} (c) extern int i; int i = 0; void foo(void) {} void bar(void) {} (d) extern int i; extern int i; void foo(void) {} void bar(void) {} What is the answer and WHY? Thanks, John
CMH117@PSUVM.BITNET (Charles Hannum) (11/16/89)
You should define a global variable in *exactly one* module, no more, no less. All other modules should refer to it as an extern. Most linkers will generate an error if a global variable by the same name is defined in more than one module. As for initializing it, that depends ... Your answer could be either B or C.
macphee@engcon.marshall.ltv.com (SCMACPHEE) (11/16/89)
If I understand the question correctly, you are trying to find out how the int variable "i" will be scoped at link time. I ran aross a similar problem using VAX 'C', and it caused me a lot of heart-ache. It appears that when declaring outside of a function, 'C' defaults the type to extern. To avoid the default extern type, declare it as static. Hope this helped! Scott engcon!macphee@uunet.uu.net LTV Missiles & Electronics Group, Dallas, Texas!
dan@charyb.COM (Dan Mick) (11/18/89)
In article <89320.012957CMH117@PSUVM.BITNET> CMH117@PSUVM.BITNET (Charles Hannum) writes: >You should define a global variable in *exactly one* module, no more, no less. >All other modules should refer to it as an extern. Most linkers will generate >an error if a global variable by the same name is defined in more than one >module. Again: What? Most PC linkers I've used will; but not Microsoft's, at least not with C 5.1, and *no* Unix linker I've ever heard of does. That seems, to me, to be one of the huge implementation-philosophy differences between Unix-oid C and PC-oid C. -- .sig files are idiotic and wasteful.
will@charyb.COM (Will Crowder) (11/18/89)
In article <312@charyb.COM> dan@charyb.UUCP (Dan Mick) writes: >In article <89320.012957CMH117@PSUVM.BITNET> CMH117@PSUVM.BITNET (Charles Hannum) writes: >> >>[comment about defining global data in only one module, and declaring >> it in the other modules used] > >Again: What? > >Most PC linkers I've used will; but not Microsoft's, at least not with C >5.1, and *no* Unix linker I've ever heard of does. That seems, to me, to >be one of the huge implementation-philosophy differences between Unix-oid >C and PC-oid C. >-- >.sig files are idiotic and wasteful. Why the "What?", Dan? The man's answer was good advice as far as I'm concerned. I prefer the PC-oid style. It just seems to make sense that since you're defining storage for one location, you define it in one place. You can declare its existence wherever you want to use it. This actually seems useful to me, since that way you can know that once you've found the definition of the variable you aren't using, you can remove it *in once place* and it's gone. Other modules which used it will get complaints. Further, the PC-oid style encourages the concept of an object module "owning" a data object. If indeed it is not appropriate for any single executable code module to own the data object, because it's used equally everywhere, then you can have a "global data" module which only defines the global data. Again, the scope and ownership of the data object is defined in the source module. Also, the PC-oid style encourages (read: requires) differentiation between the definition of an object (which reserves space), and the declaration of an object (which does not). I consider this useful: one object, one definition, multiple declarations of its existence in other source modules which use it, and might depend on its proper initialization, and which will cause complaints if the object doesn't exist at linktime. Will
walter@hpclwjm.HP.COM (Walter Murray) (11/18/89)
John Hascall writes: > I have been involved in a ``discussion'' over which (if any) of the > four following pairs of modules are identical in result. Assume that in > each case the two modules are compiled separately and linked with: > int main(int argc, char **argv) { > void foo(void); void bar(void); foo(); bar(); return(1); } > module1.c module2.c > ------------------- ------------------- > (a) int i; int i; > void foo(void) {} void bar(void) {} > > (b) extern int i; int i; > void foo(void) {} void bar(void) {} > > (c) extern int i; int i = 0; > void foo(void) {} void bar(void) {} > > (d) extern int i; extern int i; > void foo(void) {} void bar(void) {} > What is the answer and WHY? This is something that varies depending on your compiler and linker. In ANSI C, the answer is that all four cases are legal and produce the same result. > WHY? Why not? No rule has been violated. The answer would be different if 'i' were actually used somewhere (other than as part of the operand of sizeof). Then case (a) would be illegal (more than one "external definition" for 'i'), and case (d) would be illegal (no "external definition" for 'i'). Cases (b) and (c) would still be legal and have the same result. Note that a global declaration of the form "int i;" is called a tentative definition and has the same effect as "int i = 0;" if it is the only declaration for 'i' in that translation unit (module). This whole area was a major standardization issue, and the rules finally adopted by ANSI C try to accommodate as many existing environments and implementations as possible. Walter Murray ----------
tanner@cdis-1.uucp (Dr. T. Andrews) (11/20/89)
In article <316@charyb.COM>, will@charyb.COM (Will Crowder) writes:
) Further, the PC-oid style ...
The "pc-oid" style (occasionally called "ref/def" for references and
definition) pre-dates the IBM-PC. The "unix-oid" (also known as
"common") style of course also pre-dates the IBM-PC.
The term "common" is meant in the fortran sense, rather than "usual".
--
Mulroney: "Cut trains. Drive in | {bpa,uunet}!cdin-1!cdis-1!tanner
Canada. We need the acid rain." | {attctc gatech!uflorida}!ki4pv!cdis-1!tanner