storage/linkage

P

Ping Cheu

It turn out that in past I completely mix variable storage and linkage
when I saw static and external.

Now that I learned the differences, and here is my three-line report,

extern int gloabl_1; /* external storage, external linkage */
int global_2; /* static storage, external linkage */
static int global_3; /* static storage, static linkage */

Also, the static declaration causes the functions values to be retained
whether the function is in execution or not.

Please let me know if I'm wrong again.

Now my question will be: if I make executable from 2 *.c modules. In both
files I have an int global (static storage, external linkage): is there
be only one variable and where it stored?

Thankyou

Ping
 
S

Shao Miller

It turn out that in past I completely mix variable storage and linkage
when I saw static and external.

Now that I learned the differences, and here is my three-line report,

extern int gloabl_1; /* external storage, external linkage */
int global_2; /* static storage, external linkage */
static int global_3; /* static storage, static linkage */

Also, the static declaration causes the functions values to be retained
whether the function is in execution or not.

Please let me know if I'm wrong again.

It is not clear to me whether you are suggesting these as three
independent cases or as following one after the other somewhere in your
code. If there are multiple declarations and/or a definition, I believe
that the order matters.
Now my question will be: if I make executable from 2 *.c modules. In both
files I have an int global (static storage, external linkage): is there
be only one variable and where it stored?

Please consider the following:

/* my_header.h */
int x;

/* my_tu1.c */
#include "my_header.h"

/* my_tu2.c */
#include "my_header.h"

Both my_tu1.c and my_tu2.c contain tentative definitions for 'x'. When
the units are are translated, because there is no further definition for
'x', 'x' is defined to contain a zero a value and the object is defined
for both translation units ("TU").

A friendly linker that links both TUs into a program will note that
these definitions completely agree and won't complain that it was
defined multiple times.

An unfriendly linker can complain that both TUs have definitions for 'x'.

Compare with:

/* my_header.h */
extern int x;

/* my_tu1.c */
#include "my_header.h"

/* my_tu2.c */
#include "my_header.h"

In this example, 'extern' prevents any tentative definitions for 'x'.
Neither TU will have defined 'x', and if it's used, it had better be
defined in some other TU or library or whatever.

That's my understanding, anyway.
 
S

Shao Miller

Compare with:

/* my_header.h */
extern int x;

/* my_tu1.c */
#include "my_header.h"

/* my_tu2.c */
#include "my_header.h"

In this example, 'extern' prevents any tentative definitions for 'x'.
Neither TU will have defined 'x', and if it's used, it had better be
defined in some other TU or library or whatever.

To clarify, 'extern' doesn't _prevent_ any definition of 'x' from
appearing in these two TUs. In this example, no definitions for 'x'
appear in either TU.
 
J

James Kuyper

It turn out that in past I completely mix variable storage and linkage
when I saw static and external.

Now that I learned the differences, and here is my three-line report,

extern int gloabl_1; /* external storage, external linkage */
int global_2; /* static storage, external linkage */
static int global_3; /* static storage, static linkage */

The correct term is "internal linkage", not "static linkage". Also, all
three variables refer to objects with static storage duration; it's just
that two of them must be defined in the current translation unit, while
global_1 could be defined in a different translation unit.
Also, the static declaration causes the functions values to be retained
whether the function is in execution or not.

That statement is almost completely wrong.

When the key word 'static' is applied to the declaration of a function,
it gives that function's identifier internal linkage. What this means is
that the function can be referred to using that identifier only in the
current translation unit. It could be called from another translation
unit, but only by passing a function pointer to that other unit - it
could not be called by name.
Now my question will be: if I make executable from 2 *.c modules. In both
files I have an int global (static storage, external linkage): is there
be only one variable and where it stored?

6.9p5 says: "If an identifier declared with external linkage is used in
an expression ..., somewhere in the entire program there shall be
exactly one external definition for the identifier; otherwise, there
shall be no more than one." Those "shalls" do not occur inside a
constraints section, so they therefore specifies that the behavior of
your ENTIRE PROGRAM is undefined if the rule is broken (4p2).

Therefore, if you write such a program, there is nothing a conforming
implementation could do as a result of translating your code which would
make it non-conforming. It could create one variable, two variables, 0
variables, or 35232 variables with that name. It would still be
comforming no matter where it stored that(those) variable(s). The
compiler would still be conforming if it choose to ignore the entire
rest of your program and just send obscene hate mail to your boss in
your name. In other words - DONT DO THAT.
 
B

Ben Bacarisse

Ping Cheu said:
It turn out that in past I completely mix variable storage and linkage
when I saw static and external.

Now that I learned the differences, and here is my three-line report,

extern int gloabl_1; /* external storage, external linkage */
int global_2; /* static storage, external linkage */
static int global_3; /* static storage, static linkage */

Not quite. First, you need to make it clear where there lines appear. I
assume you intend them to be at file scope (i.e. outside of all
functions).

Second, all three have static storage duration. The other storage
durations are automatic and allocated. Allocated storage duration can't
apply to a named objects (it's for malloced storage) and automatic
storage duration only applies inside functions (and their parameters).

Finally, a name has either internal, external or no linkage at all --
there is no static linkage, though it's not a bad invention.

So it's:

extern int gloabl_1; /* static storage, external linkage */
int global_2; /* static storage, external linkage */
static int global_3; /* static storage, internal linkage */

The difference between 2 and 3 is that the second is a definition and
not just a declaration. (Actually, it's a "tentative definition" but
that's another story for another day).
Also, the static declaration causes the functions values to be retained
whether the function is in execution or not.

I think I know what you are getting at, but it's a little confused. Let
me re-phrase: inside a function, an object declared with the static
storage-class specifier will have static storage duration and thus will
retain its value from one call to the next.
Please let me know if I'm wrong again.

Now my question will be: if I make executable from 2 *.c modules. In both
files I have an int global (static storage, external linkage): is there
be only one variable and where it stored?

Not necessarily. What matters is how many definitions there are. If
you have

int global;

int two .c files, you won't be able to link them without undefined
behaviour. It might work on some system or other, but it's wrong. One
of them must be "extern int global;".
 

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,755
Messages
2,569,536
Members
45,012
Latest member
RoxanneDzm

Latest Threads

Top