[comp.std.c] Storage class conflicts and external linkage.

baxter@garth.UUCP (Bill Baxter) (08/20/90)

The December 1988 ANSI C draft is not real specific about the treatment of the
following situation (assume that foo and foo1 are contained in the same file):

----------------samefile.c-------------------
void
foo ( )
{
	extern void foo1( void );

	.
	.
	.
	foo1();
	.
	.
	.
}

static
foo1( )
{
	.
	.
	.
}
---------------end samefile.c------------------

The function foo declares a function foo1 with external scope and later
references that function.  However, the declaration only has block scope.
Therefore, the function foo should be calling a foo1 which has external
scope.  The foo1 in samefile.c has only static scope. 

I have the following questions:

1.  Does the standard require that the reference to foo1 in foo reference
    a foo1 not contained in samefile.c since the definition of foo1 in
    samefile.c has only static storage class?

2.  In the event that 1 is true, then would the standard require that we
    manufacture a name for one of the functions foo1 (e.g., _Static_foo1)
    to avoid the duplicate name so that the reference to foo1 in foo can
    be made global, and foo1 (more specifically _Static_foo1) can be
    reserved for internal linkage?

In response to these questions I would like specific references to the
Draft standard.

The problem actually arises quite frequently if the declaration of foo1 is
implicit (i.e., the programmer forgot to declare the function foo1 in foo).
I would argue that the implicit declaration only has block scope as well.
This is a major change in semantics over pcc/K&R compilers.  And can be
quite tricky to implement.

The standard states that the compiler is not responsible for generating
a warning when a function declaration has gone out of scope.  However, when
there is a storage class conflict (i.e., extern vs. static) the semantics
have changed.  What is the compiler's responsibility in this situation?

-- 
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Bill Baxter       Compiler Group: Advanced Processor Division      (415)852-2333
E-MAIL: {apple|pyramid}!apd!baxter      USPS: 2400 Geng Rd., Palo Alto, CA 94303
_STD_DISC:  INGR has their opinions.  I have mine.  Believe them if conflicting.

gwyn@smoke.BRL.MIL (Doug Gwyn) (08/21/90)

In article <697@garth.UUCP> baxter@garth.UUCP (Bill Baxter) writes:
- foo ( )
- {
- 	extern void foo1( void );
- }
- static
- foo1( )
- {
- }

The first declaration of "foo1" gives it external linkage, the second
gives it internal linakge, thus the behavior is explicitly undefined.

- However, the declaration only has block scope.

That's not relevant.  Linkage does not track scope.

- In response to these questions I would like specific references to the
- Draft standard.

3.1.2.2.

diamond@tkou02.enet.dec.com (diamond@tkovoa) (08/21/90)

In article <13628@smoke.BRL.MIL> gwyn@smoke.BRL.MIL (Doug Gwyn) writes:
>In article <697@garth.UUCP> baxter@garth.UUCP (Bill Baxter) writes:
>>foo ( ) { extern void foo1( void ); }
>>static foo1( ) {}
>The first declaration of "foo1" gives it external linkage, the second
>gives it internal linakge, thus the behavior is explicitly undefined.

The first "foo1" has external linkage and the second "foo1" has internal
linkage, but they are separate identifiers.  The first "foo1" goes out
of scope at the closing } of foo's block.  Section 3.1.2.1.
The following source file has two separate identifiers "bar":
 foo() { extern int bar; }   static foo1( ) { auto int bar; }
So does:
 foo() { extern int bar; }   static int bar;   static foo1( ) {}

>>However, the declaration only has block scope.
>That's not relevant.  Linkage does not track scope.

Linkage tracks identifiers, section 3.1.2.2.  Identifiers track scopes,
section 3.1.2.1.

(Incidentally, Mr. Baxter's guess that block scope applies to the first
foo1 is correct.  There is a footnote in section 3.3.2.2.)
-- 
Norman Diamond, Nihon DEC       diamond@tkou02.enet.dec.com
Steering like a sports car:  I use opinions; the company uses the rack.