Scope of specifier extern

  • Thread starter Christian Christmann
  • Start date
C

Christian Christmann

Hi,

I've a a question on the specifier extern.

Code example:

void func( void )
{
extern int e;
//...
}

int e = 2;

int main() void
{
func();
return 0;
}


Are both the func() variable 'e' and the global 'e' same
objects? Or are they distinct symbols due to different
scopes (one is local, the other is global)?
I could not find any references in the standard ISO/IEC 9899:1999.

Regards,
Chris
 
P

pete

Christian said:
Hi,

I've a a question on the specifier extern.

Code example:

void func( void )
{
extern int e;
//...
}

int e = 2;

int main() void
{
func();
return 0;
}

Are both the func() variable 'e' and the global 'e' same
objects? Or are they distinct symbols due to different
scopes (one is local, the other is global)?
I could not find any references in the standard ISO/IEC 9899:1999.

The meaning of "extern int e;" is that e is defined
as an int, outside of the block with the extern declaration.
 
T

Tom St Denis

Christian said:
Hi,

I've a a question on the specifier extern.

Code example:

void func( void )
{
extern int e;
//...
}

int e = 2;

int main() void
{
func();
return 0;
}

Yes they're the same [at least with GCC on most platforms I can think
of]. "e" will be accessed globally and "int e = 2" exports the symbol
"e".

Now, had you wrote "static int e = 2" they would be different and most
likely platform dependent.

Tom
 
C

Christian Christmann

void func( void )
{
extern int e;
//...
}

int e = 2;

int main() void
{
func();
return 0;
}

Yes they're the same [at least with GCC on most platforms I can think
of].

That's the point. I figured out that GCC is considering both 'e' as one
and the same object. However, I don't know if this strictly corresponds
to ANSI C-99.
 
T

Tom St Denis

Christian said:
That's the point. I figured out that GCC is considering both 'e' as one
and the same object. However, I don't know if this strictly corresponds
to ANSI C-99.

I don't see why not. I mean from an implementation point of view
"extern int e" just means use the symbol defined globally somewhere
else. The fact that "somewhere else" is within the same object file
doesn't really matter.

It's similar in concept to a forward declaration, e.g.

int somefunc(int);
int myfunc(int x) { return somefunc(x); }
int somefunc(int x) { return x + 1; }

You could also write it as

int myfunc(int x) { extern int somefunc(int); return somefunc(x); }
int somefunc(int x) { return x + 1; }

"gcc -pedantic --std=c99 -O2 -Wall -W"

Doesn't raise a single diagnostic at that. :)

Tom
 
C

Chris Torek

I've a a question on the specifier extern.

OK. Let me note, however, that the phrase in the subject line --
"scope of specifier" -- is not meaningful, in C. Here "specifier"
obviously refers to storage-class specifiers. There are five such,
in C: "auto", "extern", "register", "static", and the one oddball,
"typedef". But none of them have scope; scope is a property
exclusively attached to *identifiers*.

This distinction is important, as should become clear in a moment.

There are only two applicable scopes in your example: "block" and
"file". (Goto labels have a third scope, "function scope", and
identifiers inside prototypes have the fourth, "function prototype
scope", but neither of these are used here.)
Code example:

void func( void )
{
extern int e;
//...
}

Here, the identifier "e" has *block* scope. Its scope is determined
by the fact that it is declared inside a function, in the {}-pair
that delimits the function's code. The keyword "extern" affects
the identifier's *linkage* (and, in this case, storage duration),
rather than its scope.
int e = 2;

Here, the identifier "e" has *file* scope.
int main( void )
{
func();
return 0;
}


Are both the func() variable 'e' and the global 'e' same
objects? Or are they distinct symbols due to different
scopes (one is local, the other is global)?

The answer to that question is determined by "linkage", not "scope".

The "scope" concept answers the question "can I `see' that identifier
from this position in the source code?" If an identifier is in
scope, you can see it; if not, you cannot (so a reference to it
gets a diagnostic, usually along the lines of "undeclared identifier".)
(More precisely, it has to be in a *visible* scope, not hidden away
by some intermediate shadowing declaration.) The "linkage" concept
answers the question: "given two identifiers with the same name,
do they name the same object or function?"

There are three possible linkages: "internal", "external", and
"none". Two identifiers with the same name refer to the same object
or function if they have the same linkage, except of course for the
obvious case for block-scope automatic objects with "no linkage":

void f(void) { int i; ... }
void g(void) { int i; ... }

Here the two "i"s have block scope and no linkage, and are different
objects.

In your original example, the identifier "e" inside func() has
external linkage, and the identifier "e" at file scope also has
external linkage. Since the identifiers match and the linkages
match, they name the same object.

(As an aside, it may be worth noting that, in ancient K&R-1 C --
pre-C89 -- there *were* at least *some* compilers in which "extern",
used inside a function, *did* give an identifier file scope.)

If you were to replace the "int e = 2;" line with "static int e =
2;" you would end up with a single translation unit in which the
identifier "e" appears with both external and internal linkage.
In this case, the C Standards -- C89 and C99 both -- say the effect
is undefined.

For a much more complete treatment of scope and linkage and the
storage-class specifier keywords, you might also try a google-groups
search for "scope" + "linkage" + "duration" in comp.lang.c. :)
 
D

Dave Thompson

The "scope" concept answers the question "can I `see' that identifier
from this position in the source code?" If an identifier is in
scope, you can see it; if not, you cannot (so a reference to it
gets a diagnostic, usually along the lines of "undeclared identifier".)
(More precisely, it has to be in a *visible* scope, not hidden away
by some intermediate shadowing declaration.) The "linkage" concept
answers the question: "given two identifiers with the same name,
do they name the same object or function?"

There are three possible linkages: "internal", "external", and
"none". Two identifiers with the same name refer to the same object
or function if they have the same linkage, except of course for the
obvious case for block-scope automatic objects with "no linkage":

void f(void) { int i; ... }
void g(void) { int i; ... }

Here the two "i"s have block scope and no linkage, and are different
objects.
That's atypically for CT uncareful and I believe misleading wording.

Multiple identifiers with the same name and external linkage refer to
the same object or function (and must be declared compatibly).

Multiple identifiers in different translation units with the same name
and internal linkage are distinct objects or functions (or a
mixture!). Such declarations in the same t.u. refer to the same
entity, although I would call those multiple declarations of one
identifier, not declarations of multiple identifiers that are linked
-- which is approaching angels-on-pinheads territory.

Any identifier with no linkage is 'obviously' (!) always distinct.

Although in implementation, most identifiers with no linkage are for
objects with automatic duration, which usually are (but are not
formally required to be) allocated on a stack, which will often result
in some object(s) say x in one function being placed at the same
address that was previously used for say y in a different function
that was previously executed (completely = called and returned).

<snip rest>

- David.Thompson1 at worldnet.att.net
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,777
Messages
2,569,604
Members
45,216
Latest member
topweb3twitterchannels

Latest Threads

Top