[comp.lang.c] Why static forward references

chris@mimsy.UUCP (Chris Torek) (12/21/86)

In article <6927@ki4pv.UUCP> tanner@ki4pv.UUCP (Tanner Andrews) writes:
> /*  start of example */
>extern char *blunge();			/* declare blunge */
>char *gork() { return(blunge(69)); }	/* use blunge */
>static char *blunge(arg) int	arg; { /* body of blunge here */ }
> /*  end of example */

>That "extern" just isn't needed.  Why not leave it off.

Leaving it out works correctly in all Unix compilers.  For that
matter, as far as I know, it works correctly in all IBM PC compilers,
and all Mac C compilers, and so on.

The problem, you see, is that some people want to write a compiler
that grabs the `extern' and generates a link directive:

		.extern	_blunge

They also want to write (or already have) a linker that will complain
if an explicit extern clashes with a later explicit definition:

	_blunge:

Why do they want to do this?  The main reason seems to be laziness.

The Unix compilers emit assembly, and simply omit the `extern's:

	_gork:	.globl	_gork
		...
		call	_blunge
		...
	_blunge:

When _blunge is defined in the same file, this is a conventional
forward reference.  If blunge() is moved away, the assembler just
assumes that _blunge is an external symbol.  If the assembler were
more demanding, the compiler could be educated a bit to do this:

	_gork:	.globl	_gork
		...
		call	_blunge
		...
		# end of source file
		.extern	_blunge
		# and any other as-yet-undefined-but-referenced
		# symbols; uses one bit per symbol table entry

Now, even if the compiler were to generate object code directly,
it could still do this---and even if the compiler were to generate
linkable files in which an `extern' must appear before a use, it
can still do this, even trivially, simply by generating the link
file, then generating the externs file, then concatenating the link
file onto the externs file.

But if the ANSI standard mandates that the code author must use
`extern' or `static' on forward declarations, these compiler writers
can save themselves the trouble of doing things right, or of fixing
their linkers.  And that appears to be the entire motivation.

(Do you detect a tone of disgust?  Then good, for this is indeed
disgusting.)
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7690)
UUCP:	seismo!mimsy!chris	ARPA/CSNet:	chris@mimsy.umd.edu

bzs@bu-cs.BU.EDU (Barry Shein) (12/24/86)

>extern char *blunge();			/* declare blunge */
>That "extern" just isn't needed.  Why not leave it off.

Ah ha ha ha! well, sort of...gather round:

In the C code for Franz 38.92 there is a definition SPISFP.

in bigdiv.c there is (within a routine):

	int *sp();

Unfortunately, there is also in a .h file (more or less):

int *xp;
#ifdef SPISFP
#define sp() xp
#endif

Well, the clever children have guessed that this rendered that
declaration:

	int *xp;

thus hiding the global value. Took a while to find that one, it usually
worked (was used as a ptr to a dummy stack space to fake alloca().)

Anyhow...I was just thinking about this 'unnecessary' extern as I wiped
the blood from my eyes. (you can consider this a bug report on that Franz
if you like.)

	-Barry Shein, Boston University

gwyn@brl-smoke.ARPA (Doug Gwyn ) (01/05/87)

In article <4870@mimsy.UUCP> chris@mimsy.UUCP (Chris Torek) writes:
>In article <6927@ki4pv.UUCP> tanner@ki4pv.UUCP (Tanner Andrews) writes:
>>extern char *blunge();			/* declare blunge */
>>char *gork() { return(blunge(69)); }	/* use blunge */
>>static char *blunge(arg) int	arg; { /* body of blunge here */ }

>But if the ANSI standard mandates that the code author must use
>`extern' or `static' on forward declarations, these compiler writers
>can save themselves the trouble of doing things right, or of fixing
>their linkers.  And that appears to be the entire motivation.

I don't think that is the issue at all.  The question is, WHICH
"blunge" should be used in the above example?  There might be
an external blunge() function also.  According to the "declare
things correctly before you use them" school, the external
blunge() should be used, not the internal one.  The one-pass
compilation model also requires this, since the meaning of the
reference to blunge() cannot depend on goings-on lexically later
in the source file.  This becomes even more significant when one
considers the fact that the rules for internal and external
symbol names (case folding, truncation, etc.) may well differ.

P.S.  "extern" is not required for such function declarations,
forward reference or no, since a function declaration with
neither "extern" nor "static" is taken to have external linkage if
linkage hasn't already been determined by a previous declaration.

chris@mimsy.UUCP (Chris Torek) (01/06/87)

Doug Gwyn quotes something that is misleading, and seems to have
mislead:
>>In article <6927@ki4pv.UUCP> tanner@ki4pv.UUCP (Tanner Andrews) writes:
>>>extern char *blunge();			/* declare blunge */
>>>char *gork() { return(blunge(69)); }	/* use blunge */
>>>static char *blunge(arg) int	arg; { /* body of blunge here */ }

>In article <4870@mimsy.UUCP> I wrote:
>>But if the ANSI standard mandates that the code author must use
>>`extern' or `static' on forward declarations, these compiler writers
>>can save themselves the trouble of doing things right, or of fixing
>>their linkers.  And that appears to be the entire motivation.

In article <5478@brl-smoke.ARPA> gwyn@brl-smoke.ARPA (Doug Gwyn ) writes:
>I don't think that is the issue at all.  The question is, WHICH
>"blunge" should be used in the above example?

I think the static one should be used.  But we were trying to
_eliminate_ the `extern' from the first declaration.  The above
example is one we would like to eradicate.

>According to the "declare things correctly before you use them"
>school, the external blunge() should be used, not the internal
>one.

But this is not in fact what happens with any of the compilers I
have used.  (Not that I have used many C compilers.)  I also happen
to think it is a bad idea to force one to encode the visibility of
a function in its type declarations as well as in its definition,
although I can see how others would feel otherwise.
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7690)
UUCP:	seismo!mimsy!chris	ARPA/CSNet:	chris@mimsy.umd.edu