By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
424,686 Members | 2,392 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 424,686 IT Pros & Developers. It's quick & easy.

when should multiple definitions of global variables trigger link time errors?

P: n/a
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 definitions are translated
to "weak" symbols, in which case multiple definitions are merged by the
linker, while some become "normal" symbols, triggering linker errors in
case they are defined more then once. Is it true that in C++, multiple
definitions are always disallowed?

This code (2 translation units) compiles with gcc -ansi, but triggers
linker errors with g++:

//weak1.c (or weak1.cpp):
#include <stdio.h>
int a[5];
void f();
int main()
{
printf("&a=%p\n",a);
f();
}

//weak2.c (or weak2.cpp):
#include <stdio.h>
int a[10];
void f()
{
printf("f: &a=%p\n",a);
}

Compiled with gcc, it prints:

&a=0x80495e0
f: &a=0x80495e0

- showing that the definitions `int a[5]' and `int a[10]' were merged.
A symbol table listing shows that the dimension of a[] in the linked
binary is 10. Adding initializers to the definitions, for example,
triggers linker errors in C.

Thanks in advance!
Yossi

Mar 4 '06 #1
Share this Question
Share on Google+
8 Replies


P: n/a
yo***********@gmail.com wrote:
Hi!

When are multiple definitions of global variables with the same name
considered legal in C,
Never.
and how is it different from C++?
Not topical on comp.lang.c, but I would expect it to be the same.
It appears
that in terms of assembly language, some C definitions are translated
to "weak" symbols, in which case multiple definitions are merged by the
linker, while some become "normal" symbols, triggering linker errors in
case they are defined more then once.
That may be the case on some implementations, but it is not true on all.
On one of the C implementations I use regularly it will produce a link
time error on multiple definitions of a symbol, on another it won't.
That's the wonder of Undefined Behaviour, *anything* can happen.
Is it true that in C++, multiple
definitions are always disallowed?

This code (2 translation units) compiles with gcc -ansi, but triggers
linker errors with g++:
Use different options with gcc and you may get different results.
//weak1.c (or weak1.cpp):
#include <stdio.h>
int a[5];
<snip>
//weak2.c (or weak2.cpp):
#include <stdio.h>
int a[10];
<snip>

Undefined behaviour in C. Anything can happen.

<snip>
binary is 10. Adding initializers to the definitions, for example,
triggers linker errors in C.


So will selecting the correct option in some versions of gcc.
Specifically the -fno-common option. You should also use -pedantic if
you want gcc to be a fully compliant C compiler, and looking at and
enabling the other warnings would also be a good thing.
--
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
Mar 4 '06 #2

P: n/a
On 4 Mar 2006 04:34:34 -0800, in comp.lang.c , yo***********@gmail.com
wrote:
Hi!

When are multiple definitions of global variables with the same name
considered legal in C,
Never, there can be only one definition of any object.

Multiple global declarations are fine though, so long as they're the
same. Your example with two different declarations of 'a' should have
triggered a warning from your compiler, and is I believe undefined
behaviour.
and how is it different from C++?


No idea.

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

----== Posted via Newsfeeds.Com - Unlimited-Unrestricted-Secure Usenet News==----
http://www.newsfeeds.com The #1 Newsgroup Service in the World! 120,000+ Newsgroups
----= East and West-Coast Server Farms - Total Privacy via Encryption =----
Mar 4 '06 #3

P: n/a
On Sat, 04 Mar 2006 14:44:54 +0000, in comp.lang.c , Flash Gordon
<sp**@flash-gordon.me.uk> wrote:
yo***********@gmail.com wrote:
Hi!

When are multiple definitions of global variables with the same name
considered legal in C,

Use different options with gcc and you may get different results.
//weak1.c (or weak1.cpp):
#include <stdio.h>
int a[5];


<snip>
//weak2.c (or weak2.cpp):
#include <stdio.h>
int a[10];


<snip>

Undefined behaviour in C. Anything can happen.


IIRC these are declarations and tentative definitions. The fact that
they're different is indeed UB but its not illegal to have several
tentative definitions.
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

----== Posted via Newsfeeds.Com - Unlimited-Unrestricted-Secure Usenet News==----
http://www.newsfeeds.com The #1 Newsgroup Service in the World! 120,000+ Newsgroups
----= East and West-Coast Server Farms - Total Privacy via Encryption =----
Mar 4 '06 #4

P: n/a
> IIRC these are declarations and tentative definitions. The fact that
they're different is indeed UB but its not illegal to have several
tentative definitions.


Could you please explain that? If I understand correctly, you say that
`int a[5]' in both translation units are "declarations and tentative
definitions", but I don't understand exactly what that means. Does it
mean that multiple definitions are going to be allowed by the compiler,
but the behaviour is only defined when they are identical (if so,
identical on what level)? Which definitions are tentative?

TIA,
Yossi

Mar 4 '06 #5

P: n/a
Thanks!

I use -Wall -ansi -pedantic. I assumed it does the trick. Forgive me if
it's the wrong place to ask, but while we're at it - what are the
correct options to ask gcc for it's fullest standard compliance? It
looks like -ansi -pedantic are not enough.

Or is it standard compliant to ignore multiple definitions of a[],
especially if I fixed them to define the same array size? Do any
multiple definitions trigger undefined behaviour, or only different
ones?

Mar 4 '06 #6

P: n/a
Mark McIntyre <ma**********@spamcop.net> writes:
On Sat, 04 Mar 2006 14:44:54 +0000, in comp.lang.c , Flash Gordon
<sp**@flash-gordon.me.uk> wrote:
yo***********@gmail.com wrote:
Hi!

When are multiple definitions of global variables with the same name
considered legal in C,

Use different options with gcc and you may get different results.
//weak1.c (or weak1.cpp):
#include <stdio.h>
int a[5];


<snip>
//weak2.c (or weak2.cpp):
#include <stdio.h>
int a[10];


<snip>

Undefined behaviour in C. Anything can happen.


IIRC these are declarations and tentative definitions. The fact that
they're different is indeed UB but its not illegal to have several
tentative definitions.


This is only true within the same translation unit. A tentative
definition still causes the object to be defined at the end of the
unit. Since both units define it, this causes UB regardless of
disagreement on type.

-Micah
Mar 4 '06 #7

P: n/a
yo***********@gmail.com wrote:

Could you please explain that? If I understand correctly, you say that
`int a[5]' in both translation units are "declarations and tentative
definitions", but I don't understand exactly what that means.


A tentative definition is a declaration that will be interpreted as a
definition only if no other (non-tentative) definition appears in the
translation unit. In your case, there are no other definitions in the
translation units, so both of the tentative definitions are, in fact,
interpreted as definitions, resulting in multiple definitions for the
same object, which results in undefined behavior. The code is
incorrect, but there's no obligation for the compiler/linker to diagnose
it.

-Larry Jones

I've got an idea for a sit-com called "Father Knows Zilch." -- Calvin
Mar 4 '06 #8

P: n/a
On Sat, 04 Mar 2006 21:13:54 GMT, in comp.lang.c ,
la************@ugs.com wrote:
yo***********@gmail.com wrote:

Could you please explain that? If I understand correctly, you say that
`int a[5]' in both translation units are "declarations and tentative
definitions", but I don't understand exactly what that means.


A tentative definition is a declaration that will be interpreted as a
definition only if no other (non-tentative) definition appears in the
translation unit.


Agh, for some reason i had it in my head that the rule was across all
TUs.
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

----== Posted via Newsfeeds.Com - Unlimited-Unrestricted-Secure Usenet News==----
http://www.newsfeeds.com The #1 Newsgroup Service in the World! 120,000+ Newsgroups
----= East and West-Coast Server Farms - Total Privacy via Encryption =----
Mar 4 '06 #9

This discussion thread is closed

Replies have been disabled for this discussion.