Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > extern variable

Reply
Thread Tools

extern variable

 
 
deepak
Guest
Posts: n/a
 
      08-07-2009
Here is my program in three different files.

file1:
int a;
char b[10];

void
foo(int a)
{
printf("\n%d", a);
}

file2:

int a;

main()
{
foo(10);
printf("\n%d", a);
}

file3:

int a;

It's compiling and I would like to know for variable 'a' where the
definition is happening if
I compile like gcc file1.c file2.c file3.c?

If extern in missing in second and third file, how it's identifying
that it's already defined in file1.c

Please clear my doubt.

Thanks,
Deepak
 
Reply With Quote
 
 
 
 
Thomas Matthews
Guest
Posts: n/a
 
      08-07-2009
deepak wrote:
> Here is my program in three different files.
>
> file1:
> int a;
> char b[10];
>
> void
> foo(int a)
> {
> printf("\n%d", a);
> }
>
> file2:
>
> int a;
>
> main()
> {
> foo(10);
> printf("\n%d", a);
> }
>
> file3:
>
> int a;
>
> It's compiling and I would like to know for variable 'a' where the
> definition is happening if
> I compile like gcc file1.c file2.c file3.c?
>
> If extern in missing in second and third file, how it's identifying
> that it's already defined in file1.c
>
> Please clear my doubt.
>
> Thanks,
> Deepak


In the C language, a variable declared in the global space
is available to all translation units in the program. The
"linker" sees that the first file has defined the variable,
so the other two reference the same variable. It's kind of
an optimizing thing, to share the same variable. (There
is a more technical reason, but that lines in the realm of
the C language standard).

To have a variable with the same name in multiple translation
units treated as separate variables, the "static" keyword
must be used. The "static" keyword says that the variable
is only known within the translation unit and not to other
external entities.

As far as which file actually defines the variable first is
up to the linker



--
Thomas Matthews

C++ newsgroup welcome message:
http://www.slack.net/~shiva/welcome.txt
C++ Faq: http://www.parashift.com/c++-faq-lite
C Faq: http://www.eskimo.com/~scs/c-faq/top.html
alt.comp.lang.learn.c-c++ faq:
http://www.comeaucomputing.com/learn/faq/
Other sites:
http://www.josuttis.com -- C++ STL Library book
http://www.sgi.com/tech/stl -- Standard Template Library
 
Reply With Quote
 
 
 
 
Richard Bos
Guest
Posts: n/a
 
      08-07-2009
deepak <(E-Mail Removed)> wrote:

> Here is my program in three different files.


[ Snipping everything that isn't relevant... ]

> file1:
> int a;


> file2:
>
> int a;


> file3:
>
> int a;


> It's compiling and I would like to know for variable 'a' where the
> definition is happening if
> I compile like gcc file1.c file2.c file3.c?


Wherever gcc likes to put it.

In theory, this may even be nowhere, because your program has undefined
behaviour. According to 6.9.2, all three declarations of a are also
tentative definitions, and (there being no others in their respective
translation units) end up as external definitions. But according to
6.9#5, there shall only be one of those. You have three. Hence, you
break a "shall" that is outside a constraint; hence, you have undefined
behaviour.
As I wrote: in theory. In practice, gcc probably solves this by
noticing, during its linking stage, that it has collected three a's in
its public symbol table and they all have the same type, so it creates
one object with that type for all three of those identifiers to refer
to. That's how I would do it, except that I would print a warning
message, as well.
Goodness knows where it leaves that object, though. But you should not
need to care. All you should need to know is that if you correct your
code, a has external linkage (i.e., all a's refer to the same object);
it has static duration (i.e., that object is created just before your
main function starts and isn't destroyed until after your last atexit()
function ends); and since you didn't explicitly initialise this static
object, it is automatically initialised to 0; and finally, that it is
highly likely, even if not guaranteed, that this is the case even in
your broken case.

> If extern in missing in second and third file, how it's identifying
> that it's already defined in file1.c


Again: however it likes to. It is not required to by the Standard, but
it is allowed to apply whatever internal compiler magic it likes. And
again, you should not even care how: what you should do is put those
externs back where they belong. And, I suspect, increase the warning
level on your compiles.

Richard
 
Reply With Quote
 
David Thompson
Guest
Posts: n/a
 
      08-17-2009
On Fri, 07 Aug 2009 16:03:39 GMT, http://www.velocityreviews.com/forums/(E-Mail Removed) (Richard Bos)
wrote:

> deepak <(E-Mail Removed)> wrote:

<snip: three t.u.s each with int a;>

> In theory, this may even be nowhere, because your program has undefined
> behaviour. According to 6.9.2, all three declarations of a are also
> tentative definitions, and (there being no others in their respective
> translation units) end up as external definitions. But according to
> 6.9#5, there shall only be one of those. You have three. Hence, you
> break a "shall" that is outside a constraint; hence, you have undefined
> behaviour.


Right.

> As I wrote: in theory. In practice, gcc probably solves this by
> noticing, during its linking stage, that it has collected three a's in
> its public symbol table and they all have the same type, so it creates
> one object with that type for all three of those identifiers to refer
> to. That's how I would do it, except that I would print a warning
> message, as well.


People sometimes use gcc to mean just the compiler(s?), and
sometimes the driver which runs the whole sequence including linking.
But the linking 'stage' as you call it is always a separate program.
On some platforms/targets, the linker is from another GNU package
'binutils' and we can still make useful statements about it from the
GNU doc (although not strictly the gcc part), but on some platforms
gcc uses the 'native' linker. In particular, GNU ld is (I think
always) and other linkers _may_ be affected by whether (the compiler
actually invoked under) gcc marks items in the object files as
'common'; this can be controlled by -f[no-]common.

The traditional behavior for common is to take the largest size
specified by any object file = t.u., and (initial) contents specified
by some object file that does so if any do. I.e. if all files leave
the contents default = zero-bits, that is used; if only one file has
contents, those are used; if more than one file has contents, one of
them is used, but which one might vary depending on the linker.
AFAIK GNU ld always does this for common, and other linkers if they
have common at all are reasonably likely to do so. Object files
typically don't represent type in a fashion understood by the linker,
only size; and even size differences aren't usually treated as an
error because this capability was originally designed to handle COMMON
in FORTRAN, hence the name, which does allow some size differences.

GNU ld gives an error if multiple t.u.s have no-common definitions.
Other linkers may vary rather more in this mode.

Similar principles apply to many (probably all) other compilers also,
but the details vary.

> Goodness knows where it leaves that object, though. But you should not
> need to care. All you should need to know is that if you correct your
> code, a has external linkage (i.e., all a's refer to the same object);
> it has static duration (i.e., that object is created just before your
> main function starts and isn't destroyed until after your last atexit()
> function ends); and since you didn't explicitly initialise this static
> object, it is automatically initialised to 0; and finally, that it is
> highly likely, even if not guaranteed, that this is the case even in
> your broken case.
>

Agree with all of those. And add that you may not know, and shouldn't
care, where the linker puts an object even when it's coded correctly:
one definition and other nondefining references; or no references.

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Difference of extern short *x and extern short x[]? Andre C Programming 5 07-17-2012 07:38 PM
extern struct variable Bangalore C++ 5 09-06-2005 01:45 AM
extern global variable defined within namespace Dan Elliott C++ 4 12-08-2004 10:21 AM
extern const char * vs. extern const char []http://tinyurl.com/47e3k Thomas Matthews C++ 5 08-02-2004 10:36 AM
extern access to variable smackdab C Programming 1 12-08-2003 04:43 AM



Advertisments