473,406 Members | 2,369 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,406 software developers and data experts.

External object definition and linkage

After many years of dealing with definition and linkage issues
in ways that I know to be safe, I've decided it's time to try
to understand this area properly. Consider a header file with
the file scope declaration

int i;

This header is included in two files that refer to i but do not
declare it. The two files build together into a single program.

i is therefore declared once in each translation unit. According
to C99 6.2.2 the declarations have external linkage and refer to
the same object. 6.9.2 says that each declaration is a tentative
external definition, which then gets converted to an actual
external definition. There are now 2 external definitions of i
in the program, which breaks the requirement in 6.9 that there
shall be exactly one external definition, so this results in
undefined behavior.

Have I got this right? Confirmation or correction appreciated.
Nov 14 '05 #1
19 2856
On 2 Apr 2004 13:05:42 -0800, jj*@bcs.org.uk (J. J. Farrell) wrote:
After many years of dealing with definition and linkage issues
in ways that I know to be safe, I've decided it's time to try
to understand this area properly. Consider a header file with
the file scope declaration

int i;

This header is included in two files that refer to i but do not
declare it. The two files build together into a single program.

i is therefore declared once in each translation unit. According
to C99 6.2.2 the declarations have external linkage and refer to
the same object. 6.9.2 says that each declaration is a tentative
external definition, which then gets converted to an actual
external definition. There are now 2 external definitions of i
in the program, which breaks the requirement in 6.9 that there
shall be exactly one external definition, so this results in
undefined behavior.

Have I got this right? Confirmation or correction appreciated.


The language of 6.9.2/2 is, IMHO, horribly ambiguous. Here's it is (I've
used quotes to indicate what is in italics in the Standard):

-----------------
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.
----------------

So what's that word "declaration" doing there on the next-to-last line? How
can a "declaration" have an "initializer equal to 0" (or behave "as if" it
had one) without being considered "the definition" of the object across all
TU's? I don't know.

Note that this is not within a constraints section, and therefore whatever
it means, the compiler is not obliged to produce a diagnostic if it is
violated. So it could in fact be saying that there's only supposed to be
one, but if an implementation carries the "tentativeness" over to the link
phase, and it works as someone would expect it to (or be used to it working
from a historical basis), that isn't necessarily a non-conforming
implementation.

[Admission: I had some help from Greg Comeau on this, and he essentially
confirmed my own confusion about it all. But I hadn't thought about the
implications of it not being in a constraints section...]
-leor


--
Leor Zolman --- BD Software --- www.bdsoft.com
On-Site Training in C/C++, Java, Perl and Unix
C++ users: Download BD Software's free STL Error Message Decryptor at:
www.bdsoft.com/tools/stlfilt.html
Nov 14 '05 #2
"J. J. Farrell" wrote:

After many years of dealing with definition and linkage issues
in ways that I know to be safe, I've decided it's time to try
to understand this area properly. Consider a header file with
the file scope declaration

int i;

This header is included in two files that refer to i but do not
declare it. The two files build together into a single program.

i is therefore declared once in each translation unit. According
to C99 6.2.2 the declarations have external linkage and refer to
the same object. 6.9.2 says that each declaration is a tentative
external definition, which then gets converted to an actual
external definition. There are now 2 external definitions of i
in the program, which breaks the requirement in 6.9 that there
shall be exactly one external definition, so this results in
undefined behavior.

Have I got this right? Confirmation or correction appreciated.


You're right.

The usual practice (for any externally-linked object or
function) is to put a declaration, not a definition, in a
header file, and to #include that header wherever it's needed.
The actual definition goes in one and only one .c file, which
itself also #include's the header (so the compiler can complain
if the declaration and the definition disagree).

In your case, the header would say

extern int i;

.... where "extern" means, roughly, "this is just a declaration;
there's a matching definition somewhere else." For a function
you could say

extern int func(void);

.... except it turns out that "extern" is unnecessary (although
harmless) here: The compiler can tell it's not a definition
because there's no `{...}' function body.

One final point: Many people feel that "global variables"
are Bad, mostly because they can create hard-to-see couplings
between apparently unrelated parts of the program. I'm less
bitterly opposed to them than some denizens hereabouts, but
whenever I stick a global variable into my program I pause
and consider whether this is *really* the right thing to do.
Quite often, it isn't.

--
Er*********@sun.com
Nov 14 '05 #3
On Fri, 02 Apr 2004 18:31:34 -0500, Eric Sosman <Er*********@sun.com>
wrote:

The usual practice (for any externally-linked object or
function) is to put a declaration, not a definition, in a
header file, and to #include that header wherever it's needed.
The actual definition goes in one and only one .c file, which
itself also #include's the header (so the compiler can complain
if the declaration and the definition disagree).

In your case, the header would say

extern int i;

... where "extern" means, roughly, "this is just a declaration;
there's a matching definition somewhere else."


Being my usual literal-minded-self, I answered the OP's specific question
the best I could...but now I feel obliged to add that the way Eric says to
do things is of course the /right/ way to set up inter-TU linkage, since it
is completely unambiguous and works the same in both C and C++.

Trying to understand the situation where "int i;" appears at file scope in
multiple TU's is seems better to be left an exercise in Standard
decryption, and probably shouldn't be allowed to become a practical matter
;-)
-leor

--
Leor Zolman --- BD Software --- www.bdsoft.com
On-Site Training in C/C++, Java, Perl and Unix
C++ users: Download BD Software's free STL Error Message Decryptor at:
www.bdsoft.com/tools/stlfilt.html
Nov 14 '05 #4
"J. J. Farrell" wrote:

After many years of dealing with definition and linkage issues
in ways that I know to be safe, I've decided it's time to try
to understand this area properly. Consider a header file with
the file scope declaration

int i;

This header is included in two files that refer to i but do not
declare it. The two files build together into a single program.
and is thus a mistake. You omitted the word "extern".

i is therefore declared once in each translation unit. According
to C99 6.2.2 the declarations have external linkage and refer to
the same object. 6.9.2 says that each declaration is a tentative
external definition, which then gets converted to an actual
external definition. There are now 2 external definitions of i
in the program, which breaks the requirement in 6.9 that there
shall be exactly one external definition, so this results in
undefined behavior.

Have I got this right? Confirmation or correction appreciated.


No. Header files should only specify the exposure of elements in
the source. They should not declare any data or functions.

--
Chuck F (cb********@yahoo.com) (cb********@worldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net> USE worldnet address!
Nov 14 '05 #5
CBFalconer wrote:

"J. J. Farrell" wrote:

After many years of dealing with definition and linkage issues
in ways that I know to be safe, I've decided it's time to try
to understand this area properly. Consider a header file with
the file scope declaration

int i;

This header is included in two files that refer to i but do not
declare it. The two files build together into a single program.


and is thus a mistake. You omitted the word "extern".

i is therefore declared once in each translation unit. According
to C99 6.2.2 the declarations have external linkage and refer to
the same object. 6.9.2 says that each declaration is a tentative
external definition, which then gets converted to an actual
external definition. There are now 2 external definitions of i
in the program, which breaks the requirement in 6.9 that there
shall be exactly one external definition, so this results in
undefined behavior.

Have I got this right? Confirmation or correction appreciated.


No. Header files should only specify the exposure of elements in
the source. They should not declare any data or functions.


Quick, change that 'declare' to 'define', before the rats get at
it.

--
Chuck F (cb********@yahoo.com) (cb********@worldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net> USE worldnet address!

Nov 14 '05 #6

"Leor Zolman" <le**@bdsoft.com> wrote in message
news:m7********************************@4ax.com...
On 2 Apr 2004 13:05:42 -0800, jj*@bcs.org.uk (J. J. Farrell) wrote:
After many years of dealing with definition and linkage issues
in ways that I know to be safe, I've decided it's time to try
to understand this area properly. Consider a header file with
the file scope declaration

int i;

This header is included in two files that refer to i but do not
declare it. The two files build together into a single program.

i is therefore declared once in each translation unit. According
to C99 6.2.2 the declarations have external linkage and refer to
the same object. 6.9.2 says that each declaration is a tentative
external definition, which then gets converted to an actual
external definition. There are now 2 external definitions of i
in the program, which breaks the requirement in 6.9 that there
shall be exactly one external definition, so this results in
undefined behavior.

Have I got this right? Confirmation or correction appreciated.
The language of 6.9.2/2 is, IMHO, horribly ambiguous. Here's it is (I've
used quotes to indicate what is in italics in the Standard):

-----------------
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. ----------------

So what's that word "declaration" doing there on the next-to-last line? How can a "declaration" have an "initializer equal to 0" (or behave "as if" it
had one) without being considered "the definition" of the object across all TU's? I don't know.
I don't think it can - that's the point. I guess they avoided "definition"
since this is the section that's defining "definition".
Note that this is not within a constraints section, and therefore whatever
it means, the compiler is not obliged to produce a diagnostic if it is
violated. So it could in fact be saying that there's only supposed to be
one, but if an implementation carries the "tentativeness" over to the link
phase, and it works as someone would expect it to (or be used to it working from a historical basis), that isn't necessarily a non-conforming
implementation.


I think it just means that it results in undefined behaviour. The
pre-standard compilers that implemented the 'common model' can continue
to do so, and other compilers don't have to do anything in particular.

Nov 14 '05 #7

"Leor Zolman" <le**@bdsoft.com> wrote in message
news:m7********************************@4ax.com...
On 2 Apr 2004 13:05:42 -0800, jj*@bcs.org.uk (J. J. Farrell) wrote:
After many years of dealing with definition and linkage issues
in ways that I know to be safe, I've decided it's time to try
to understand this area properly. Consider a header file with
the file scope declaration

int i;

This header is included in two files that refer to i but do not
declare it. The two files build together into a single program.

i is therefore declared once in each translation unit. According
to C99 6.2.2 the declarations have external linkage and refer to
the same object. 6.9.2 says that each declaration is a tentative
external definition, which then gets converted to an actual
external definition. There are now 2 external definitions of i
in the program, which breaks the requirement in 6.9 that there
shall be exactly one external definition, so this results in
undefined behavior.

Have I got this right? Confirmation or correction appreciated.
The language of 6.9.2/2 is, IMHO, horribly ambiguous. Here's it is (I've
used quotes to indicate what is in italics in the Standard):

-----------------
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. ----------------

So what's that word "declaration" doing there on the next-to-last line? How can a "declaration" have an "initializer equal to 0" (or behave "as if" it
had one) without being considered "the definition" of the object across all TU's? I don't know.
I don't think it can - that's the point. I guess they avoided "definition"
since this is the section that's defining "definition".
Note that this is not within a constraints section, and therefore whatever
it means, the compiler is not obliged to produce a diagnostic if it is
violated. So it could in fact be saying that there's only supposed to be
one, but if an implementation carries the "tentativeness" over to the link
phase, and it works as someone would expect it to (or be used to it working from a historical basis), that isn't necessarily a non-conforming
implementation.


I think it just means that it results in undefined behaviour. The
pre-standard compilers that implemented the 'common model' can continue
to do so, and other compilers don't have to do anything in particular.

Nov 14 '05 #8

"Eric Sosman" <Er*********@sun.com> wrote in message
news:40***************@sun.com...
"J. J. Farrell" wrote:

After many years of dealing with definition and linkage issues
in ways that I know to be safe, I've decided it's time to try
to understand this area properly. Consider a header file with
the file scope declaration

int i;

This header is included in two files that refer to i but do not
declare it. The two files build together into a single program.

i is therefore declared once in each translation unit. According
to C99 6.2.2 the declarations have external linkage and refer to
the same object. 6.9.2 says that each declaration is a tentative
external definition, which then gets converted to an actual
external definition. There are now 2 external definitions of i
in the program, which breaks the requirement in 6.9 that there
shall be exactly one external definition, so this results in
undefined behavior.

Have I got this right? Confirmation or correction appreciated.
You're right.


Thanks.
The usual practice (for any externally-linked object or
function) is to put a declaration, not a definition, in a
header file, and to #include that header wherever it's needed.
The actual definition goes in one and only one .c file, which
itself also #include's the header (so the compiler can complain
if the declaration and the definition disagree).


Indeed. An alternative to avoid listing all the variables in
two places is for the header to contain something like

#if defined(DEFINE_GLOBALS)
#define EXTDECL
#else
#define EXTDECL extern
#endif
EXTDECL char global;

and then define DEFINE_GLOBALS in exactly one .c file before
including the header. Not exactly elegant, but it avoids
duplicating a list of variables, and avoids all the bugs that
come from not getting the duplication right and up to date.

The aim of this exercise was to make sure I understood if any
other ways of doing it are valid, and to be able to give a
better answer than "because I said so" or "because that's what
the Standard says" when people don't believe that that's the
only right way to do it.

Nov 14 '05 #9

"Eric Sosman" <Er*********@sun.com> wrote in message
news:40***************@sun.com...
"J. J. Farrell" wrote:

After many years of dealing with definition and linkage issues
in ways that I know to be safe, I've decided it's time to try
to understand this area properly. Consider a header file with
the file scope declaration

int i;

This header is included in two files that refer to i but do not
declare it. The two files build together into a single program.

i is therefore declared once in each translation unit. According
to C99 6.2.2 the declarations have external linkage and refer to
the same object. 6.9.2 says that each declaration is a tentative
external definition, which then gets converted to an actual
external definition. There are now 2 external definitions of i
in the program, which breaks the requirement in 6.9 that there
shall be exactly one external definition, so this results in
undefined behavior.

Have I got this right? Confirmation or correction appreciated.
You're right.


Thanks.
The usual practice (for any externally-linked object or
function) is to put a declaration, not a definition, in a
header file, and to #include that header wherever it's needed.
The actual definition goes in one and only one .c file, which
itself also #include's the header (so the compiler can complain
if the declaration and the definition disagree).


Indeed. An alternative to avoid listing all the variables in
two places is for the header to contain something like

#if defined(DEFINE_GLOBALS)
#define EXTDECL
#else
#define EXTDECL extern
#endif
EXTDECL char global;

and then define DEFINE_GLOBALS in exactly one .c file before
including the header. Not exactly elegant, but it avoids
duplicating a list of variables, and avoids all the bugs that
come from not getting the duplication right and up to date.

The aim of this exercise was to make sure I understood if any
other ways of doing it are valid, and to be able to give a
better answer than "because I said so" or "because that's what
the Standard says" when people don't believe that that's the
only right way to do it.

Nov 14 '05 #10

"CBFalconer" <cb********@yahoo.com> wrote in message
news:40***************@yahoo.com...
CBFalconer wrote:

"J. J. Farrell" wrote:

After many years of dealing with definition and linkage issues
in ways that I know to be safe, I've decided it's time to try
to understand this area properly. Consider a header file with
the file scope declaration

int i;

This header is included in two files that refer to i but do not
declare it. The two files build together into a single program.


and is thus a mistake. You omitted the word "extern".

i is therefore declared once in each translation unit. According
to C99 6.2.2 the declarations have external linkage and refer to
the same object. 6.9.2 says that each declaration is a tentative
external definition, which then gets converted to an actual
external definition. There are now 2 external definitions of i
in the program, which breaks the requirement in 6.9 that there
shall be exactly one external definition, so this results in
undefined behavior.

Have I got this right? Confirmation or correction appreciated.


No. Header files should only specify the exposure of elements in
the source. They should not declare any data or functions.


Quick, change that 'declare' to 'define', before the rats get at
it.


Thanks Chuck, but I'm confused by the "no". Are you saying it's not
undefined behaviour, or that it is undefined behaviour but my reasons
why are wrong, or something else?

Nov 14 '05 #11

"CBFalconer" <cb********@yahoo.com> wrote in message
news:40***************@yahoo.com...
CBFalconer wrote:

"J. J. Farrell" wrote:

After many years of dealing with definition and linkage issues
in ways that I know to be safe, I've decided it's time to try
to understand this area properly. Consider a header file with
the file scope declaration

int i;

This header is included in two files that refer to i but do not
declare it. The two files build together into a single program.


and is thus a mistake. You omitted the word "extern".

i is therefore declared once in each translation unit. According
to C99 6.2.2 the declarations have external linkage and refer to
the same object. 6.9.2 says that each declaration is a tentative
external definition, which then gets converted to an actual
external definition. There are now 2 external definitions of i
in the program, which breaks the requirement in 6.9 that there
shall be exactly one external definition, so this results in
undefined behavior.

Have I got this right? Confirmation or correction appreciated.


No. Header files should only specify the exposure of elements in
the source. They should not declare any data or functions.


Quick, change that 'declare' to 'define', before the rats get at
it.


Thanks Chuck, but I'm confused by the "no". Are you saying it's not
undefined behaviour, or that it is undefined behaviour but my reasons
why are wrong, or something else?

Nov 14 '05 #12
"J. J. Farrell" <jj*@bcs.org.uk> wrote:

<snip>
Indeed. An alternative to avoid listing all the variables in
two places is for the header to contain something like

#if defined(DEFINE_GLOBALS)
#define EXTDECL
#else
#define EXTDECL extern
#endif
EXTDECL char global;


This is however a bad chosen example, since macros that begin
with E followed by a digit or an uppercase letter are reserved
for future library extensions.

Regards
--
Irrwahn Grausewitz (ir*******@freenet.de)
welcome to clc: http://www.ungerhu.com/jxh/clc.welcome.txt
clc faq-list : http://www.faqs.org/faqs/C-faq/faq/
clc OT guide : http://benpfaff.org/writings/clc/off-topic.html
Nov 14 '05 #13
"J. J. Farrell" <jj*@bcs.org.uk> wrote:

<snip>
Indeed. An alternative to avoid listing all the variables in
two places is for the header to contain something like

#if defined(DEFINE_GLOBALS)
#define EXTDECL
#else
#define EXTDECL extern
#endif
EXTDECL char global;


This is however a bad chosen example, since macros that begin
with E followed by a digit or an uppercase letter are reserved
for future library extensions.

Regards
--
Irrwahn Grausewitz (ir*******@freenet.de)
welcome to clc: http://www.ungerhu.com/jxh/clc.welcome.txt
clc faq-list : http://www.faqs.org/faqs/C-faq/faq/
clc OT guide : http://benpfaff.org/writings/clc/off-topic.html
Nov 14 '05 #14
"J. J. Farrell" wrote:
"CBFalconer" <cb********@yahoo.com> wrote in message
CBFalconer wrote:
"J. J. Farrell" wrote:

After many years of dealing with definition and linkage issues
in ways that I know to be safe, I've decided it's time to try
to understand this area properly. Consider a header file with
the file scope declaration

int i;

This header is included in two files that refer to i but do not
declare it. The two files build together into a single program.

and is thus a mistake. You omitted the word "extern".
i is therefore declared once in each translation unit. According
to C99 6.2.2 the declarations have external linkage and refer to
the same object. 6.9.2 says that each declaration is a tentative
external definition, which then gets converted to an actual
external definition. There are now 2 external definitions of i
in the program, which breaks the requirement in 6.9 that there
shall be exactly one external definition, so this results in
undefined behavior.

Have I got this right? Confirmation or correction appreciated.

No. Header files should only specify the exposure of elements in
the source. They should not declare any data or functions.


Quick, change that 'declare' to 'define', before the rats get at
it.


Thanks Chuck, but I'm confused by the "no". Are you saying it's
not undefined behaviour, or that it is undefined behaviour but my
reasons why are wrong, or something else?


No, you haven't got it right.

--
A: Because it fouls the order in which people normally read text.
Q: Why is top-posting such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Nov 14 '05 #15
"J. J. Farrell" wrote:
"CBFalconer" <cb********@yahoo.com> wrote in message
CBFalconer wrote:
"J. J. Farrell" wrote:

After many years of dealing with definition and linkage issues
in ways that I know to be safe, I've decided it's time to try
to understand this area properly. Consider a header file with
the file scope declaration

int i;

This header is included in two files that refer to i but do not
declare it. The two files build together into a single program.

and is thus a mistake. You omitted the word "extern".
i is therefore declared once in each translation unit. According
to C99 6.2.2 the declarations have external linkage and refer to
the same object. 6.9.2 says that each declaration is a tentative
external definition, which then gets converted to an actual
external definition. There are now 2 external definitions of i
in the program, which breaks the requirement in 6.9 that there
shall be exactly one external definition, so this results in
undefined behavior.

Have I got this right? Confirmation or correction appreciated.

No. Header files should only specify the exposure of elements in
the source. They should not declare any data or functions.


Quick, change that 'declare' to 'define', before the rats get at
it.


Thanks Chuck, but I'm confused by the "no". Are you saying it's
not undefined behaviour, or that it is undefined behaviour but my
reasons why are wrong, or something else?


No, you haven't got it right.

--
A: Because it fouls the order in which people normally read text.
Q: Why is top-posting such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Nov 14 '05 #16
In <40***************@yahoo.com> CBFalconer <cb********@yahoo.com> writes:
"J. J. Farrell" wrote:
"CBFalconer" <cb********@yahoo.com> wrote in message
CBFalconer wrote:
"J. J. Farrell" wrote:
>
> After many years of dealing with definition and linkage issues
> in ways that I know to be safe, I've decided it's time to try
> to understand this area properly. Consider a header file with
> the file scope declaration
>
> int i;
>
> This header is included in two files that refer to i but do not
> declare it. The two files build together into a single program.

and is thus a mistake. You omitted the word "extern".

> i is therefore declared once in each translation unit. According
> to C99 6.2.2 the declarations have external linkage and refer to
> the same object. 6.9.2 says that each declaration is a tentative
> external definition, which then gets converted to an actual
> external definition. There are now 2 external definitions of i
> in the program, which breaks the requirement in 6.9 that there
> shall be exactly one external definition, so this results in
> undefined behavior.
>
> Have I got this right? Confirmation or correction appreciated.

No. Header files should only specify the exposure of elements in
the source. They should not declare any data or functions.

Quick, change that 'declare' to 'define', before the rats get at
it.


Thanks Chuck, but I'm confused by the "no". Are you saying it's
not undefined behaviour, or that it is undefined behaviour but my
reasons why are wrong, or something else?


No, you haven't got it right.


He (J. J. Farrell) has got it perfectly right. It was presented as a C
question, not as an example of good coding practice. And his analysis
of his problem was correct: there are two external definitions for i,
one in each translation unit, and this leads to undefined behaviour.

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 14 '05 #17
In <40***************@yahoo.com> CBFalconer <cb********@yahoo.com> writes:
"J. J. Farrell" wrote:
"CBFalconer" <cb********@yahoo.com> wrote in message
CBFalconer wrote:
"J. J. Farrell" wrote:
>
> After many years of dealing with definition and linkage issues
> in ways that I know to be safe, I've decided it's time to try
> to understand this area properly. Consider a header file with
> the file scope declaration
>
> int i;
>
> This header is included in two files that refer to i but do not
> declare it. The two files build together into a single program.

and is thus a mistake. You omitted the word "extern".

> i is therefore declared once in each translation unit. According
> to C99 6.2.2 the declarations have external linkage and refer to
> the same object. 6.9.2 says that each declaration is a tentative
> external definition, which then gets converted to an actual
> external definition. There are now 2 external definitions of i
> in the program, which breaks the requirement in 6.9 that there
> shall be exactly one external definition, so this results in
> undefined behavior.
>
> Have I got this right? Confirmation or correction appreciated.

No. Header files should only specify the exposure of elements in
the source. They should not declare any data or functions.

Quick, change that 'declare' to 'define', before the rats get at
it.


Thanks Chuck, but I'm confused by the "no". Are you saying it's
not undefined behaviour, or that it is undefined behaviour but my
reasons why are wrong, or something else?


No, you haven't got it right.


He (J. J. Farrell) has got it perfectly right. It was presented as a C
question, not as an example of good coding practice. And his analysis
of his problem was correct: there are two external definitions for i,
one in each translation unit, and this leads to undefined behaviour.

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 14 '05 #18
Irrwahn Grausewitz <ir*******@freenet.de> wrote in message news:<ce********************************@4ax.com>. ..
"J. J. Farrell" <jj*@bcs.org.uk> wrote:
An alternative to avoid listing all the variables in
two places is for the header to contain something like

#if defined(DEFINE_GLOBALS)
#define EXTDECL
#else
#define EXTDECL extern
#endif
EXTDECL char global;


This is however a bad chosen example, since macros that begin
with E followed by a digit or an uppercase letter are reserved
for future library extensions.


Aaaargh! Thanks, Irrwahn. I'd normally use some context-specific
prefix on the macros which would avoid this. Using more "obvious"
names in the example turned out to be a mistake ...
Nov 14 '05 #19
Irrwahn Grausewitz <ir*******@freenet.de> wrote in message news:<ce********************************@4ax.com>. ..
"J. J. Farrell" <jj*@bcs.org.uk> wrote:
An alternative to avoid listing all the variables in
two places is for the header to contain something like

#if defined(DEFINE_GLOBALS)
#define EXTDECL
#else
#define EXTDECL extern
#endif
EXTDECL char global;


This is however a bad chosen example, since macros that begin
with E followed by a digit or an uppercase letter are reserved
for future library extensions.


Aaaargh! Thanks, Irrwahn. I'd normally use some context-specific
prefix on the macros which would avoid this. Using more "obvious"
names in the example turned out to be a mistake ...
Nov 14 '05 #20

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

6
by: Adam Bozanich | last post by:
Hi all. I am porting a C program I wrote to C++. I am having some issues with external variables. In C, I can have global variables declared in common header files, but I get "multiple...
47
by: Richard Hayden | last post by:
Hi, I have the following code: /******************************** file1.c #include <iostream> extern void dummy(); inline int testfunc() {
9
by: maxw_cc | last post by:
Hi to all, To explain my question I'll help myself with the following two code snippets: /*** file1.c ***/ #include <stdio.h> void print_it(void);
12
by: J. J. Farrell | last post by:
After many years of dealing with definition and linkage issues in ways that I know to be safe, I've decided it's time to try to understand this area properly. Consider a header file with the file...
4
by: Peter Ammon | last post by:
I would like to share a variable between two functions defined in two separate source files; no other functions will need the global variable so I'd prefer to not give it file scope. Thus, I want...
3
by: al.cpwn | last post by:
do static and inline functions or members have internal linkage? I have been reading this newsgroup on google and found conflicting ideas. Can someone please help me understand why in some places...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.