extern

F

Flash Gordon

Old said:
Firstly, it is /tentative definition/, not declaration.

Your correct, I meant tentative definition.
Also, Mark McIntyre was taking about objects.

As am I mainly, I just mentioned that functions where different because
with a function declaration the extern keyword does not matter.
The tentative definition in question has external linkage.

Yes, which means that it can be accessed from another translation unit.
The object it identifies must also have external linkage --
whether it is later explicitly declared or not.

Mark McIntyre's comment seems correct; I don't understand the
distinction you draw between an object being "an extern",
vs. "having external linkage".

Possibly because the standard talks about linkage and the extern keyword
separately?

When talking about linkage, the defines three types of linkage, none,
internal and external.

None is irrelevant to our discussion since the standard say, "The
following identifiers have no linkage: an identifier declared to be
anything other than an object or a function; an identifier declared to
be a function parameter; a block scope identifier for an object declared
without the storage-class specifier extern."

Internal linkage is irrelevant since that is static objects, to quote,
"If the declaration of a file scope identifier for an object or a
function contains the storage class specifier static, the identifier has
internal linkage."

So obviously a variable either declared extern or defined at file scope
has external linkage. I.e. the linkage is external in the translation
unit that defines the storage and the translation units that only
reference it.

You have accepted that something like:
int i;
is a tentative definition when given at file scope. I also quoted that
at the end of the translation unit that becomes a an actual definition.

Annex A.2 Undefined behaviour, is only informative, not normative, but
it gives the clearest statement that having multiple definitions (which
having "int i;" at file scope in more than one translation unit gives
you) is undefined behaviour. It gives as one example of undefined behaviour:

"An identifier with external linkage is used, but in the program there
does not exist exactly one external definition for the identifier, or
the identifier is not used and there exist multiple external definitions
for the identifier (6.9)."

Two definitions, whether the variable is used or not, falls fouls of
this rule.
 
F

Flash Gordon

Mark said:
(of two files with int a; in them)



Really?

Yes, really. See my reply to Old Wolf.
> The standard makes it pretty clear that in the absence of a
storage class specifier, a file-scope object is considered to be
extern. And FWIW I can't recall a compiler that behaves otherwise than
to consider two such declarations to be synonyms.

I can. gcc with the right option and MS VC 2003 when building a dll and
accessing it from a program. gcc with the correct option causes a linker
error, and IIRC MS VC creates something that does not work as expected.
> I confess, my
initial thought was the same as yours, but closer reading of the
standard deconvinced me. Can you point me to the actual section that
confirms your view?

See my reply to Old Wolf.
 
M

Mark McIntyre

On 22 Jul 2005 00:27:27 GMT, in comp.lang.c , Chris Torek

(as usual, a lucid explanation).

Thanks Chris and netocrat for the explanation.
 
O

Old Wolf

Flash said:
Possibly because the standard talks about linkage and the extern keyword
separately?

So you are using "an extern" to mean "something declared with
the keyword 'extern'". I (and Mark McIntyre, apparently), use
"an extern" to mean "something with external linkage".
 
F

Flash Gordon

Old said:
So you are using "an extern" to mean "something declared with
the keyword 'extern'". I (and Mark McIntyre, apparently), use
"an extern" to mean "something with external linkage".

Isn't life fun when people use terminology differently. In my mind, it
is important to know if something is defined in a module or merely
referenced, and in any case extern is a keyword with specific meaning,
so I use extern with the meaning it has when attached to a variable (or
function). This seems obvious to me. However, if to you it reads as
shorthand for external linkage, that's life. I don't see the point in
arguing about informal terminology. However, IIRC, the discussion was
started with an example showing something like, "int a;" *without*
extern in two files.
 
N

Netocrat

6.2.2p4 fully defines the meaning of the extern keyword, and that is as
an external linkage declarator. An exception is made that where a
variable was previously declared with the static keyword, a later
declaration with the extern keyword does not reverse the original
internal linkage of the object, but clearly the general case is that
extern == external linkage.

Which is exactly what it seems to be defined to be.
Isn't life fun when people use terminology differently. In my mind, it
is important to know if something is defined in a module or merely
referenced, and in any case extern is a keyword with specific meaning,
so I use extern with the meaning it has when attached to a variable (or
function).

And what meaning is that?

<snip>
 
R

Richard Bos

Netocrat said:
6.2.2p4 fully defines the meaning of the extern keyword, and that is as
an external linkage declarator. An exception is made that where a
variable was previously declared with the static keyword, a later
declaration with the extern keyword does not reverse the original
internal linkage of the object, but clearly the general case is that
extern == external linkage.

No, it isn't. Declared extern usually implies external linkage, but not
v.v. Most objects and functions with external linkage are not declared
extern.
Which is exactly what it seems to be defined to be.

Which of the two? With external linkage, or _explicitly_ declared with
external linkage? There's the whole point of this sub-thread, I think.

Richard
 
N

Netocrat

Richard said:
No, it isn't. Declared extern usually implies external linkage, but not
v.v. Most objects and functions with external linkage are not declared
extern.

"==" was the wrong thing to write, and not what I intended. Instead
substitute "means".
Which of the two? With external linkage, or _explicitly_ declared with
external linkage? There's the whole point of this sub-thread, I think.

Right, again unclearly worded. I meant that "an extern" is defined as
"something with external linkage" (with the noted exception) but did
not intend to imply the reverse.

6.2.2 also specifies that for a function-scope variable declaration,
linkage is external regardless of whether the extern keyword is used or
ommitted (so long as static is not used).
 
N

Netocrat

6.2.2 also specifies that for a function-scope variable declaration,
linkage is external regardless of whether the extern keyword is used or
ommitted (so long as static is not used).

Ack, they just keep on rolling off my keyboard. Obviously I meant
file-scope, not function-scope.
 
J

Joe Wright

Richard said:
No, it isn't. Declared extern usually implies external linkage, but not
v.v. Most objects and functions with external linkage are not declared
extern.




Which of the two? With external linkage, or _explicitly_ declared with
external linkage? There's the whole point of this sub-thread, I think.

Richard

I didn't really choose this as response to Bos' post but as a place to
jump in. By default, functions and variables defined at file scope have
external linkage. This means that the compiler will provide a symbol
table or somesuch in the .o file in case than any other translation unit
might use the function or variable. This symbol table is information for
the linker so that it knows how to create an executable with information
from two or more .o files which would share information.

A second (or subsequent) translation unit that would call a function
from another can simply do so. The linker takes care of resolving this
call with the symbol table of the first translation unit.

In the general case, for a project with two or more translation units,
we can write a header, "proj.h", for inclusion in all translation units
which 'declare' for the compiler the myriad 'definitions' of functions
and variables among the translation units.

In the simple case, consider proj.h like..

int foo(int);
extern int bar;

Neither of these declarations makes a mark on the executable. They do
NOT create code. They are clues to the compiler. foo is a function. Call
it this way. bar is an int defined elsewhere (or here). It's yours.

In one and only one of the translation units we need a definition..

int foo(int i) {return i;}

...and in one and only one we need the definition at file scope..

int bar;

Now code in any of the translation units can could be..

bar = foo(1);

...with no confusion among the translation units about foo or bar.
 

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

Similar Threads

Question about extern keyword 7
linking problem? | extern keyword 6
Problems in creating libraries 0
extern pointers. 5
Distributed array initialization 11
extern 10
extern variable 3
extern int *a , int a[10] 6

Members online

Forum statistics

Threads
474,167
Messages
2,570,911
Members
47,453
Latest member
MadelinePh

Latest Threads

Top