Re: "extern" question?



On 15 Aug 2006 12:27:14 -0700, "jchludzinski@xxxxxxxxx"
<jchludzinski@xxxxxxxxx> wrote in comp.lang.c:

I have 3 files (see below: a.h, w.c, ww.c). I would like to use a
single x (declared somewhere) which would global to both compilation
units: w.c & ww.c. No matter where I place the "extern" qualifier - it
appears to work: x is shared between w.c and ww.c. Or if I simple
don't use "extern", it works. Why? What is the correct (or simply
preferred) usage?

The only CORRECT usage is to have one and only definition of the
object (a declaration without the extern keyword, or a declaration
with an initializer with or without the extern keyword) in one
translation unit, and a declaration with the extern keyword and no
initializer in every other translation unit that references the
object.

The preferred usage, is to put the external declaration (with extern,
without initializer) in a header and include that header in all
translation units that reference the object, including the one that
defines it.

PS> I'm using gcc (GCC) 4.0.2.

/*---------------a.h-----------------*/
#ifndef _A_H

Here is something else that is not CORRECT. You violate the language
standard when you define identifiers beginning with two underscores,
or an underscore followed by an upper case letter, in your code. All
such identifiers with this pattern are reserved for the implementation
(compiler). Change this.

#define _A_H

extern int x;
void g( void );

#endif /* _A_H */

/*---------------w.c-----------------*/
#include <stdio.h>
#include <stdlib.h>
#include "a.h"

int x;

void g( void )
{
x = 12;
fprintf( stderr, "x = %d\n", x );
}

/*---------------ww.c-----------------*/
#include <stdio.h>
#include <stdlib.h>
#include "a.h"

int x;

int main( int argc, char *argv[] )
{
g();
x = 144;
fprintf( stderr, "x = %d\n", x );
g();
fprintf( stderr, "x = %d\n", x );
}

The C standard is quite specific about external definitions for
objects or functions. For an object or function that appears in an
external declaration but is not referenced by the program, there may
be either zero or one external definition. For an object or function
in an external declaration that is referenced by the program, there
must be exactly one and only one external definition. If a program
violates these conditions, the result is undefined behavior.

In your snippets, you show three different files that each have an
external definition of the int object x. That invokes undefined
behavior, since you have more than one definition. Once you produce
undefined behavior, the C standard no longer knows or cares what
happens, One possible result of undefined behavior is the program
might do what you expected it to do.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~ajo/docs/FAQ-acllc.html
.



Relevant Pages

  • Re: Clarification required for linkage.
    ... According to me int g;is the tentative definition of g and it has ... linkage as if the "extern" keyword had been present. ... If the declaration of an identifier for a function has no storage- ...
    (comp.lang.c)
  • Re: extern variable
    ... If extern in missing in second and third file, ... is available to all translation units in the program. ... exactly one external definition for the identifier; ...
    (comp.lang.c)
  • Re: keyword extern
    ... >> definition or declaration until the end of the translation unit being ... >> One never needs to use the extern keyword with a function definition, ... >> ...then here is how a C compiler understands them. ... If any code in the source file access 'x', ...
    (comp.lang.c)
  • Re: "extern" inside a block
    ... In multi source file programs, ... > I know the behaviour when extern declaration follows a non-extern ... Linkage of Identifiers ... scope in which a prior declaration of that identifier is visible [and ...
    (comp.lang.c)
  • Re: extern
    ... > (of two files with int a; ... behaves as if it had been declared extern int a = 0; ... If the declaration of an identifier for ... function named by the identifier is a definition. ...
    (comp.lang.c)