Xref: utzoo comp.lang.c:25827 comp.std.c:2450 Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!wuarchive!usc!samsung!aplcen!haven!adm!smoke!gwyn From: gwyn@smoke.BRL.MIL (Doug Gwyn) Newsgroups: comp.lang.c,comp.std.c Subject: Re: extern int f(); VS int f(); Keywords: Storage Classes, External References Message-ID: <12115@smoke.BRL.MIL> Date: 11 Feb 90 02:58:47 GMT References: <2912@hcx1.SSD.CSD.HARRIS.COM> Reply-To: gwyn@brl.arpa (Doug Gwyn) Followup-To: comp.lang.c Organization: Ballistic Research Lab (BRL), APG, MD. Lines: 70 In article <2912@hcx1.SSD.CSD.HARRIS.COM> brad@SSD.CSD.HARRIS.COM (Brad Appleton) writes: >Are the following function declarations equivalent? >(1) extern int foo(); >(2) int foo(); >When would I use (1) and not (2) (and vice-versa)? >Is this dependent on the Compiler Vendor? >Is the answer different between ANSI-C and non-ANSI C? This is a messy issue, because existing implementations differed in this. The Standard situation for functions is simpler than for objects; the latter involves the notion of "tentative definition" as well as linkage. I'm just going to explain linkage here. First, be sure you know the difference between object (data) and function. Next, recall that there are four scopes of identifier visibility: function-scope (labels only) function-prototype scope (parameters in declarations only) file-scope (declared outside blocks) block-scope (declared inside a block, also parameters in definitions) Inner declarations can hide outer ones until the inner scope terminates. Finally, linkage is determined as follows: if not object and not function or function parameter or block-scope and object and not specified "extern" then no linkage; done fi if function and no storage-class-specifier then set storage-class-specifier to "extern"; proceed fi if specified "extern" { object or function } then if there was a visible file-scope declaration then linkage is same as visible file-scope's; done else linkage is external; done fi fi if file-scope then case storage-class-specifier in "static": linkage is internal; done none: { object } linkage is external; done esac fi If the same identifier has both internal and external linkage within the same translation unit (source module including headers), the behavior is undefined. If an identifier has no linkage, it is denotes a unique entity. All instances of the same identifier with internal linkage in the same translation unit denote the same object or function. All instances of the same identifier with external linkage in the entire program denote the same object or function. Fortunately there is a simple set of rules the programmer can use to avoid the "grey areas" of the linkage rules: Always declare objects and functions that will be defined by some other translation unit or library with explicit "extern". Always define objects and functions that are published for other translation units to use without a storage-class-specifier. Always define functions and file-scope objects that are NOT intended for use by other translation units with explicit "static". If you're using a header file to define externally-visible interfaces (a recommended practice), always use "extern" in its object and function declarations (but not in type definitions). >I am somewhat new to the net and would also appreciate some constructive >feedback on whether this issue is worthy/appropriate for this newsgroup! It's a legitimate question.