By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,194 Members | 884 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,194 IT Pros & Developers. It's quick & easy.

Scope of specifier extern

P: n/a
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
Jun 30 '06 #1
Share this Question
Share on Google+
7 Replies


P: n/a
Christian Christmann wrote:

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.

--
pete
Jun 30 '06 #2

P: n/a

Christian Christmann wrote:
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

Jun 30 '06 #3

P: n/a
On Fri, 30 Jun 2006 04:55:43 -0700, Tom St Denis wrote:

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.

Jun 30 '06 #4

P: n/a
pete wrote:

Christian Christmann wrote:

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


Should be "scope of" instead of "block with"
the extern declaration.


--
pete
Jun 30 '06 #5

P: n/a
Christian Christmann wrote:
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

Jun 30 '06 #6

P: n/a
In article <pa****************************@yahoo.de>
Christian Christmann <pl*****@yahoo.de> wrote:
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. :-)
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (4039.22'N, 11150.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
Jun 30 '06 #7

P: n/a
On 30 Jun 2006 18:31:36 GMT, Chris Torek <no****@torek.netwrote:

<snip example>
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
Jul 10 '06 #8

This discussion thread is closed

Replies have been disabled for this discussion.