R
RG (Rafael Giusti)
I'm having some trouble understanding the rationale for C99 when it
comes to external linkage... The rationale says (Section 6.2.2, near
line 25):
"The Standard model is a combination of features of the strict ref/def
model and the initialization model. As in the strict ref/def model,
only a single translation unit contains the definition of a given
object because many environments cannot effectively or efficiently
support the "distributed definition" inherent in the common or relaxed
ref/def approaches. However, either an initialization, or an
appropriate declaration without storage class specifier (see §6.9),
serves as the external definition. This composite approach was chosen
to accommodate as wide a range of environments and existing
implementations as possible."
What confuses me is the the following assertion: "only a single
translation unit contains the definition of a given object". To help
me illustrate my point, here's a program, which consists of two
translation units:
/* slave.c */
#include <stdio.h>
int external_object;
void print(void)
{
printf("%d\n", external_object);
}
/* main.c */
int external_object;
void print(void);
int main(void)
{
external_object = 8;
print();
return 0;
}
Well, if I compile and run this program, I'll get 8 as output. No
problem so far.
However, if I am to analyze the output of nm for both slave.o and
main.o object files, here's what I get:
main.o:
00000004 C external_object
00000000 T main
U print
slave.o:
00000004 C external_object
00000000 T print
U printf
Now, the ANSI C99 standard says the following about declarations and
definitions (Section 6.7, §5):
A declaration specifies the interpretation and attributes of a set of
identifiers. A definition of an identifier is a declaration for that
identifier that:
-- for an object, causes storage to be reserved for that object;
Well, according to nm, both main.o and slave.o reserve storage for the
object external_object, and should be considered definitions of
external_object. Hence, GCC breaks the standard by allowing more than
one definition of the external_object and then letting the linker
decide that all but one definition of external_object are actually
declarations, just like the relaxed ref/def demands!
Is that possible? What am I missing here?
Thans!
rg
comes to external linkage... The rationale says (Section 6.2.2, near
line 25):
"The Standard model is a combination of features of the strict ref/def
model and the initialization model. As in the strict ref/def model,
only a single translation unit contains the definition of a given
object because many environments cannot effectively or efficiently
support the "distributed definition" inherent in the common or relaxed
ref/def approaches. However, either an initialization, or an
appropriate declaration without storage class specifier (see §6.9),
serves as the external definition. This composite approach was chosen
to accommodate as wide a range of environments and existing
implementations as possible."
What confuses me is the the following assertion: "only a single
translation unit contains the definition of a given object". To help
me illustrate my point, here's a program, which consists of two
translation units:
/* slave.c */
#include <stdio.h>
int external_object;
void print(void)
{
printf("%d\n", external_object);
}
/* main.c */
int external_object;
void print(void);
int main(void)
{
external_object = 8;
print();
return 0;
}
Well, if I compile and run this program, I'll get 8 as output. No
problem so far.
However, if I am to analyze the output of nm for both slave.o and
main.o object files, here's what I get:
main.o:
00000004 C external_object
00000000 T main
U print
slave.o:
00000004 C external_object
00000000 T print
U printf
Now, the ANSI C99 standard says the following about declarations and
definitions (Section 6.7, §5):
A declaration specifies the interpretation and attributes of a set of
identifiers. A definition of an identifier is a declaration for that
identifier that:
-- for an object, causes storage to be reserved for that object;
Well, according to nm, both main.o and slave.o reserve storage for the
object external_object, and should be considered definitions of
external_object. Hence, GCC breaks the standard by allowing more than
one definition of the external_object and then letting the linker
decide that all but one definition of external_object are actually
declarations, just like the relaxed ref/def demands!
Is that possible? What am I missing here?
Thans!
rg