Vladimir S. Oka wrote:
fctk wrote: Vladimir S. Oka ha scritto: Maybe you should try thinking about this particular example in this
way:
static int bar;
Tells the compiler that `bar` is "visible" only internally to the file
in question.
int bar;
Then tells the compiler that it is "visible" externally as well.
Logically, both can't be true at the same time, hence the error.
mmh... but i think there is another error. `static int bar' and `int
bar' are two *definitions* other than two declarations. they are two
definitions of the *same* object.
it is as if i wrote:
static void f1(void) {}
extern void f1(void) {}
isn't it?
Yes, that too. I was just pointing out the other discrepancy.
Actually no, they are both tentative definitions, where as you example
with functions shows definitions. For example, the following is
completely legal:
static int bar; /* tentative definition */
static int bar; /* tentative definition */
static int bar; /* tentative definition */
static int bar; /* tentative definition */
static int bar = 5; /* definition */
This defines only one object named bar which is of type int and is
initialised to 5.
From section 6.9.2 of n1124.pdf
| A declaration of an identifier for an object that has file scope
| without an initializer, and without a storage-class specifier or with
| the storage-class specifier static, constitutes a tentative
^^^^^^^^^
| definition. If a translation unit contains one or more tentative
^^^^^^^^^^
| definitions for an identifier, and the translation unit contains no
| external definition for that identifier, then the behavior is exactly
| as if the translation unit contains a file scope declaration of that
| identifier, with the composite type as of the end of the translation
| unit, with an initializer equal to 0.
Here is example 1 from the same section:
int i1 = 1; // definition, external linkage
static int i2 = 2; // definition, internal linkage
extern int i3 = 3; // definition, external linkage
int i4; // tentative definition, external linkage
static int i5; // tentative definition, internal linkage
int i1; // valid tentative definition, refers to pre vious
int i2; // 6.2.2 renders undefined, linkage disagreement
int i3; // valid tentative definition, refers to pre vious
int i4; // valid tentative definition, refers to pre vious
int i5; // 6.2.2 renders undefined, linkage disagreement
extern int i1; // refers to pre vious, whose linkage is external
extern int i2; // refers to pre vious, whose linkage is internal
extern int i3; // refers to pre vious, whose linkage is external
extern int i4; // refers to pre vious, whose linkage is external
extern int i5; // refers to pre vious, whose linkage is internal
Note that there are only two problem lines in the above example, delete
(or correct) those two lines and it would be completely legal C99 (if
not for the // style comments it would be legal C89 as well).
--
Flash Gordon, living in interesting times.
Web site -
http://home.flash-gordon.me.uk/
comp.lang.c posting guidelines and intro:
http://clc-wiki.net/wiki/Intro_to_clc