473,239 Members | 1,467 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,239 software developers and data experts.

multiple global variable definitions

Suppose I declare a global variable

int g;

in two different files say a.c which has main() and b.c

When I compile them to build an executable under gcc in Redhat Linux
with the command

gcc -std=c99 -pedantic -Wall -Wextra a.c b.c

there is no linker error.

I thought there should be linker error because of two definitions for
the same global variable.

Where am I going wrong ?

Mar 19 '07 #1
10 3462

<su**************@yahoo.comwrote in message
news:11**********************@e65g2000hsc.googlegr oups.com...
Suppose I declare a global variable

int g;

in two different files say a.c which has main() and b.c

When I compile them to build an executable under gcc in Redhat Linux
with the command

gcc -std=c99 -pedantic -Wall -Wextra a.c b.c

there is no linker error.

I thought there should be linker error because of two definitions for
the same global variable.

Where am I going wrong ?
Global variables declared in the .c file have file scope. You have two
different variables, the same as declaring the same "int i" as a local
variable in two different functions. They have the same name, but
do not overlap in scope.

There would be only one variable if one file declared the variable to
be"extern".
Mar 19 '07 #2
su**************@yahoo.com, India said:
Suppose I declare a global variable

int g;

in two different files say a.c which has main() and b.c

When I compile them to build an executable under gcc in Redhat Linux
with the command

gcc -std=c99 -pedantic -Wall -Wextra a.c b.c

there is no linker error.

I thought there should be linker error because of two definitions for
the same global variable.

Where am I going wrong ?
They are only "tentative" definitions, not actual definitions. There is,
however, no such thing as a "tentative initialisation", so change them
both to:

int g = 0;

and watch the compiler (or rather the linker) choke.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
Mar 19 '07 #3
Richard Heathfield wrote:
>su**************@yahoo.com, India said:
>Suppose I declare a global variable
int g;
in two different files say a.c which has main() and b.c
there is no linker error.

I thought there should be linker error because of two definitions for
the same global variable.

They are only "tentative" definitions, not actual definitions. There is,
however, no such thing as a "tentative initialisation", so change them
both to:

int g = 0;

and watch the compiler (or rather the linker) choke.
Trying to understand the standard, from N1124:

"6. Language
....
6.9 External Definitions
....
6.9.2 External object definitions
Semantics
....
2 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."

Although I expect the behavior that the OP
described, the paragraph above seems to contradict
it:

int g; "is exactly as" int g = 0;

What I am missing?

Also, can somebody clarify the meaning of "with
the composite type as of the end of the
translation unit" (I am not sure if I am
struggling with an unclear text, of with the fact
that English is not my native language.)

Roberto Waltman

[ Please reply to the group,
return address is invalid ]
Mar 19 '07 #4
Fred Kleinschmidt wrote, On 19/03/07 14:36:
<su**************@yahoo.comwrote in message
news:11**********************@e65g2000hsc.googlegr oups.com...
>Suppose I declare a global variable

int g;

in two different files say a.c which has main() and b.c

When I compile them to build an executable under gcc in Redhat Linux
with the command

gcc -std=c99 -pedantic -Wall -Wextra a.c b.c

there is no linker error.

I thought there should be linker error because of two definitions for
the same global variable.

Where am I going wrong ?
Your mistake is assuming that the linker is required to catch your
error. It isn't.
Global variables declared in the .c file have file scope. You have two
different variables, the same as declaring the same "int i" as a local
variable in two different functions. They have the same name, but
do not overlap in scope.

There would be only one variable if one file declared the variable to
be"extern".
With neither being declared as extern it invokes undefined behaviour, so
anything is allowed to happen and the implementation (compiler/linker)
is not required to generate an error for it. The most common things to
happen are for the two "int i" definitions to be merged or for an error
to be generated.
--
Flash Gordon
Mar 19 '07 #5
Richard Heathfield wrote, On 19/03/07 15:52:
su**************@yahoo.com, India said:
>Suppose I declare a global variable

int g;

in two different files say a.c which has main() and b.c

When I compile them to build an executable under gcc in Redhat Linux
with the command

gcc -std=c99 -pedantic -Wall -Wextra a.c b.c

there is no linker error.

I thought there should be linker error because of two definitions for
the same global variable.

Where am I going wrong ?

They are only "tentative" definitions, not actual definitions.
Irrelevant as far as the standard is concerned. As soon as it reaches
the end of the translation unit it is as if there was a definition with
an initialiser equal to 2. Section 6.9.2 paragraph 2 of N1124.
There is,
however, no such thing as a "tentative initialisation", so change them
both to:

int g = 0;

and watch the compiler (or rather the linker) choke.
It may not since it is undefined behaviour either way. See above and
section 6.9 paragraph 5.

To the OP, it does not generate an error because it is not required to.
It also is not required to "work", it could do anything.

<OT>
If using gcc you might want to investigate the -fno-common option.
</OT>
--
Flash Gordon
Mar 19 '07 #6
Flash Gordon said:
Richard Heathfield wrote, On 19/03/07 15:52:
>su**************@yahoo.com, India said:
>>Suppose I declare a global variable

int g;

in two different files say a.c which has main() and b.c

When I compile them to build an executable under gcc in Redhat Linux
with the command

gcc -std=c99 -pedantic -Wall -Wextra a.c b.c

there is no linker error.

I thought there should be linker error because of two definitions
for the same global variable.

Where am I going wrong ?

They are only "tentative" definitions, not actual definitions.

Irrelevant as far as the standard is concerned.
I'll take that hit...
As soon as it reaches
the end of the translation unit it is as if there was a definition
with an initialiser equal to 2.
....but this puzzles me. Did you mean 0?

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
Mar 19 '07 #7
"Roberto Waltman" <us****@rwaltman.netwrote in message
news:mn********************************@4ax.com...
Richard Heathfield wrote:
>>su**************@yahoo.com, India said:
>>Suppose I declare a global variable
int g;
in two different files say a.c which has main() and b.c
there is no linker error.

I thought there should be linker error because of two definitions for
the same global variable.
The C standard doesn't require a linker error if you have two definitions of
the same global variable. It's undefined behaviour (6.9#5). Whether you
get an error or not is up to the implementation.
>>They are only "tentative" definitions, not actual definitions. [...]
....
Although I expect the behavior that the OP
described, the paragraph above seems to contradict
it:

int g; "is exactly as" int g = 0;

What I am missing?
Nothing. If a translation unit contains a tentative definition, then either
it also contains a "real" definition, or the behaviour is as if it contained
a "real" definition. Either way, having two translation units that define
the same identifier with external linkage (tentatively or otherwise) is
undefined behaviour.
Also, can somebody clarify the meaning of "with
the composite type as of the end of the
translation unit" (I am not sure if I am
struggling with an unclear text, of with the fact
that English is not my native language.)
Consider this translation unit:

int arr[ 10 ];
int arr[];

It contains two tentative definitions that declare "arr" with two different
types: "int[10]" and "int[]". The composite type is "arr[10]", and
therefore the behaviour is as if "arr" were defined like this:

int arr[10] = { 0 };

rather than like this:

int arr[] = { 0 };

Mar 19 '07 #8
On Mon, 19 Mar 2007 17:26:50 +0000, in comp.lang.c , Richard
Heathfield <rj*@see.sig.invalidwrote:
>Flash Gordon said:
>As soon as it reaches
the end of the translation unit it is as if there was a definition
with an initialiser equal to 2.

...but this puzzles me. Did you mean 0?
2 would be more entertaining though, don't you think? Shame its not
allowed...

--
Mark McIntyre

"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are,
by definition, not smart enough to debug it."
--Brian Kernighan
Mar 19 '07 #9
Richard Heathfield wrote, On 19/03/07 17:26:
Flash Gordon said:
>Richard Heathfield wrote, On 19/03/07 15:52:
>>su**************@yahoo.com, India said:

Suppose I declare a global variable

int g;

in two different files say a.c which has main() and b.c

When I compile them to build an executable under gcc in Redhat Linux
with the command

gcc -std=c99 -pedantic -Wall -Wextra a.c b.c

there is no linker error.

I thought there should be linker error because of two definitions
for the same global variable.

Where am I going wrong ?
They are only "tentative" definitions, not actual definitions.
Irrelevant as far as the standard is concerned.

I'll take that hit...
Just goes to show that those claiming you never accept a correction are
wrong. Something I already knew.
>As soon as it reaches
the end of the translation unit it is as if there was a definition
with an initialiser equal to 2.

...but this puzzles me. Did you mean 0?
Yes, so that's 1 all then :-)
--
Flash Gordon
Mar 19 '07 #10
On Mon, 19 Mar 2007 14:36:43 GMT, "Fred Kleinschmidt"
<fr******************@boeing.comwrote:
>
<su**************@yahoo.comwrote in message
news:11**********************@e65g2000hsc.googlegr oups.com...
Suppose I declare a global variable

int g;

in two different files say a.c [...] and b.c [...]
there is no linker error.

I thought there should be linker error because of two definitions for
the same global variable.

Where am I going wrong ?
Global variables declared in the .c file have file scope. You have two
different variables, the same as declaring the same "int i" as a local
variable in two different functions. They have the same name, but
do not overlap in scope.
Not really. Each of these is a tentative definition, and assuming
there is no other definition of the same name (at file scope) with an
initializer, the tentative definition becomes/produces a (definitive?)
definition. So you have two t.u.s both defining the same object (name)
with external linkage, which is Undefined Behavior. The implementation
is allowed to diagnose this, and in some implementations (and some
options of some implementations) it does produce a linker error, but
this is not required, and some don't.

If you declared/defined it with storage class 'static' in each t.u.,
then you would (always) have two distinct objects.
There would be only one variable if one file declared the variable to
be"extern".
That is the right way to do it, yes. More precisely, one t.u. should
define it, which is accomplished if you give no storage class, ior if
you have an initializer (even if you also specify storage class
'extern'); and the other t.u. (or in general all other t.u.s) should
declare it with 'extern' and no initializer.

Apr 15 '07 #11

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

Similar topics

10
by: Matt | last post by:
Greetings, What are people's thoughts on global variables in C++? Why are we taught not to use them in programming? Is it true that if you are running two copies of the C program one copy can...
9
by: Daniel Moree | last post by:
I'm using MS VC++ 6.0 I'm working on a big project. I've currently have several files for this project. Here's the problem. I have one header file phead.h I have two code files main.cpp and...
5
by: Charles L | last post by:
Can someone explain to me what the following means? "C permits multiple definitions of a variable in any given namespace, provided the definitions are the same and it generates only a single...
10
by: Kleenex | last post by:
Reason: I am working on an embedded project which has very limited memory (under 512 bytes, 60 or so of which is stack space), which translates into limited stack space. In order to save on stack...
14
by: Carramba | last post by:
hi! I have program with several funktion witch are in separete files, I have one include file were I have definet some variables and initiated 'const double fVar=0.874532;' this files is includet...
9
by: lbj137 | last post by:
I have two files: A.c and B.c. In both files I define a global variable, int xxxx; When I compile with a green hills compiler (and also i think with a GNU compiler) I get no errors or warnings....
8
by: yossi.kreinin | last post by:
Hi! When are multiple definitions of global variables with the same name considered legal in C, and how is it different from C++? It appears that in terms of assembly language, some C...
6
by: Gaijinco | last post by:
I'm having a weird error compiling a multiple file project: I have three files: tortuga.h where I have declared 5 global variables and prototypes for some functions. tortuga.cpp where I...
112
by: istillshine | last post by:
When I control if I print messages, I usually use a global variable "int silent". When I set "-silent" flag in my command line parameters, I set silent = 1 in my main.c. I have many functions...
0
by: abbasky | last post by:
### Vandf component communication method one: data sharing ​ Vandf components can achieve data exchange through data sharing, state sharing, events, and other methods. Vandf's data exchange method...
2
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 7 Feb 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:30 (7.30PM). In this month's session, the creator of the excellent VBE...
0
by: stefan129 | last post by:
Hey forum members, I'm exploring options for SSL certificates for multiple domains. Has anyone had experience with multi-domain SSL certificates? Any recommendations on reliable providers or specific...
0
Git
by: egorbl4 | last post by:
Скачал я git, хотел начать настройку, а там вылезло вот это Что это? Что мне с этим делать? ...
1
by: davi5007 | last post by:
Hi, Basically, I am trying to automate a field named TraceabilityNo into a web page from an access form. I've got the serial held in the variable strSearchString. How can I get this into the...
0
by: MeoLessi9 | last post by:
I have VirtualBox installed on Windows 11 and now I would like to install Kali on a virtual machine. However, on the official website, I see two options: "Installer images" and "Virtual machines"....
0
by: DolphinDB | last post by:
The formulas of 101 quantitative trading alphas used by WorldQuant were presented in the paper 101 Formulaic Alphas. However, some formulas are complex, leading to challenges in calculation. Take...
0
by: Aftab Ahmad | last post by:
Hello Experts! I have written a code in MS Access for a cmd called "WhatsApp Message" to open WhatsApp using that very code but the problem is that it gives a popup message everytime I clicked on...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...

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.