Proper use of "extern" ...

Gregory Smith greg at utcsri.UUCP
Fri Jun 13 03:57:20 AEST 1986


In article <132 at danews.UUCP> lvc at danews.UUCP (Larry Cipriani) writes:
>My understanding of extern is that it simply declares the
>object in question.  That is, the compiler is told what
>type the object is.  I don't know of any other use for extern.
>
>> f uses g and g is declared after f (I know we can put g before
>> f and the following is no longer applicable but ...).
>>
>> At the top of this file do we put
>> a) static void g() 	or
>> b) extern void g()?	(extern static must be meaningless).

Yes, extern static is a systax error. only one storage class may be specified.

>> My understanding (this varies with the book you read) of "extern" is that
>> it means the object is declared "later in this file or in another file" in
>> which case I vote for (b). Is this right?
>
>Yes, but for the wrong reason.
>
I don't think the reason is wrong. Choice (b) is wrong: It not only declares
the type of v but asserts it as static. consider this:

static foo(),blat();
extern bar(),xxx();

static blat(){}
bar(){}
foo(){}

/* "foo.c", line 6: redeclaration of foo */

On line 6 I try to pass off foo as a non-static ( externally visible )
function when I have already declared it to be static. Everything else
works ok.

'nm foo.o', after deleting last declaration, includes this:
00000008 T _bar		; bar defined inside and usable externally.
00000000 t _blat	; blat defined inside, but not externally defined.

xxx is not included. I guess what Larry is saying is " extern xxx();
obviously does not declare xxx to be in another file" which is a good
point - there need exist no xxx for the above to work. However I don't
think the distinction is a reliable one:

>I often put ALL of the declarations in one header file, and include
>it in all the other files.  This is a matter of style, and I recognize
>its weaknesses, but I like it better than all the alternatives.  By the
>way, extra, redundant, or unnecessary externs are allowed and don't matter,
>at least on my C compiler.
>-- 
what about extra, redundant, or unnecessary adjectives? :-) no offense,
I just couldn't resist that :-).
Actually, I think this is mostly a result of the behaviour of the UNIX
assemblers. All undefined symbols are assumed by the assembler to be
defined externally. So the compiler does not include any declarations
for these in its output. As a result, 'xxx' will not appear in the
assembler file at all. Some assemblers require external references to
be declared as such, and thus the compiler might emit '.extern xxx' even
though xxx is never used. That would then cause the linker to try to
load xxx. I don't know whether such behaviour is considered 'standard C'
or not.

The whole area of C external definitions is a bit of a mess. A main
problem is that the default storage class depends on the type of the
identifier, and can be different from any explicit storage class. I.e.
the following are all different:

	int x;
	static int x;
	extern int x;

These are equivalent:
	char *foo();
	extern char *foo();

Also, 'storage class' is a misnomer, since all external objects live in
static storage. And what about typedef? On the other hand, I feel
that K&R does explain all this weirdness very well. That may be because
I was already familiar with linking loaders before using C.

-- 
"Shades of scorpions! Daedalus has vanished ..... Great Zeus, my ring!"
----------------------------------------------------------------------
Greg Smith     University of Toronto      UUCP: ..utzoo!utcsri!greg



More information about the Comp.lang.c mailing list