473,657 Members | 2,832 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

multiple definitions....


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. Only
when I initialize xxxx to two different values in A.c and B.c
respectively do I get a 'multiple definitions' error. I was under the
impression that I would get such an error even without initializing
xxxx twice, simply because i am (ostensibly) allocating memory for it
twice. what is going on here?

Nov 14 '05 #1
9 2785
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

lb****@yahoo.co m wrote:
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. Only
when I initialize xxxx to two different values in A.c and B.c
respectively do I get a 'multiple definitions' error. I was under the
impression that I would get such an error even without initializing
xxxx twice, simply because i am (ostensibly) allocating memory for it
twice. what is going on here?


While this is not strictly a C issue (at least I don't think it is), and thus
is off topic here, I think that a short explanation might help.

Compilers can be smart. If they see that a global is allocated but not
initialized, they can just make space for it in their map of where data is
stored, but not actually generate the instructions/data to fill in the space.

When a global is allocated by more than one translation unit, the linker (or
what ever performs that task) can attempt to resolve the 'space left for the
global' into a usable (load image, execution image, 'core' ) form.

When both tu initialize the global, the linker can't decide which
initialization to use, and you get a multiple definition error.

When only one tu initializes the global, the linker uses that tu's allocation,
and fills in the blanks into the tu that didn't initialize the global.

When neither tu initialize the global, the linker allocates it directly, and
fills in the blanks in both of the tu's.

In other words, you can allocate a global in multpile translation units, but
you are only permitted to give it an initial value in one of those TUs.

- --
Lew Pitcher

Master Codewright & JOAT-in-training | GPG public key available on request
Registered Linux User #112576 (http://counter.li.org/)
Slackware - Because I know what I'm doing.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.4 (GNU/Linux)

iD8DBQFCshw0agV FX4UWr64RAtdeAJ 9GRAARlW4hIHJmC r3JBWVmacGRFACb BPVp
dJ46PHXfhoXTfNx 4KEjSXmM=
=z5/3
-----END PGP SIGNATURE-----
Nov 14 '05 #2

Le 17/06/2005 01:32, dans
11************* *********@z14g2 00...legr oups.com, «*lb****@yahoo. com*»
<lb****@yahoo.c om> a écrit*:

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. Only
when I initialize xxxx to two different values in A.c and B.c
respectively do I get a 'multiple definitions' error. I was under the
impression that I would get such an error even without initializing
xxxx twice, simply because i am (ostensibly) allocating memory for it
twice. what is going on here?


Make your variables "static", or use "extern" and one initialization.

The standard allows multiple declarations, but only one initialization (see
section 6.2.2 of ISO 9899-1999). If there is no "static" or "extern"
specifier, "extern" is assumed, hence there is no problem in your program
if you initialize one of your variables or none. I think it's preferable
to explicitly use "extern", to remember there are other declarations.

The standard says both variables represent the same object, and in practice,
they share data in memory. I don't know if the standard
allows you use different types (say, "int c" and "char c" in different
files), but at least it works in my version of gcc, and both variables
share the same space, again.

Nov 14 '05 #3

Le 17/06/2005 02:59, dans BE************* *************** **@laposte.net,
«*Jean-Claude Arbaut*» <je************ ****@laposte.ne t> a écrit*:
The standard allows multiple declarations, but only one initialization (see
section 6.2.2 of ISO 9899-1999). If there is no "static" or "extern"
specifier, "extern" is assumed, hence there is no problem in your program
if you initialize one of your variables or none. I think it's preferable
to explicitly use "extern", to remember there are other declarations.

The standard says both variables represent the same object, and in practice,
they share data in memory. I don't know if the standard
allows you use different types (say, "int c" and "char c" in different
files), but at least it works in my version of gcc, and both variables
share the same space, again.


About different types: the standard says the identifiers represent the same
object, however section 6.7 says

"All declarations in the same scope that refer to the same object or
function shall specify compatible types."

So same object doesn't necessarily mean same type ? (otherwise why enforce
that restriction ?). That would mean the "int c","char c" example is
allowed.

Nov 14 '05 #4

Le 17/06/2005 02:41, dans _Z************* *******@news20. bellglobal.com,
«*Lew Pitcher*» <lp******@sympa tico.ca> a écrit*:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

lb****@yahoo.co m wrote:
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. Only
when I initialize xxxx to two different values in A.c and B.c
respectively do I get a 'multiple definitions' error. I was under the
impression that I would get such an error even without initializing
xxxx twice, simply because i am (ostensibly) allocating memory for it
twice. what is going on here?


While this is not strictly a C issue (at least I don't think it is), and thus
is off topic here, I think that a short explanation might help.


It seems to me that's a question on declaration, so perfectly on-topic.
Nov 14 '05 #5
On 16 Jun 2005 16:32:29 -0700, lb****@yahoo.co m wrote in comp.lang.c:

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. Only
when I initialize xxxx to two different values in A.c and B.c
respectively do I get a 'multiple definitions' error. I was under the
impression that I would get such an error even without initializing
xxxx twice, simply because i am (ostensibly) allocating memory for it
twice. what is going on here?


Your code generates undefined behavior, and anything can happen, the C
standard washes its hands and takes no responsibility for the results.

C has rules about external declarations of functions or objects in a
program. There are only two of them and they are quite simple:

1. If the external object or function is not actually used by the
program, there may be exactly 0 or 1 definitions of it in the program.

2. If the external object is accessed or the external function is
called, there must be exactly 1 definition of it in the program.

In your case, if you define the same object or function with external
linkage in two different translation units, you break both of these
rules, producing undefined behavior. At that point, as far as C is
concerned, anything can happen. Once you define the object in two
different translation units in the same program, the program is no
longer valid C, so the fact that you can change the (undefined)
behavior by breaking the rule in different ways is not a C language
issue.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.l earn.c-c++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html
Nov 14 '05 #6
On Thu, 16 Jun 2005 16:32:29 -0700, lbj137 wrote:

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. Only
when I initialize xxxx to two different values in A.c and B.c
respectively do I get a 'multiple definitions' error. I was under the
impression that I would get such an error even without initializing
xxxx twice, simply because i am (ostensibly) allocating memory for it
twice. what is going on here?


Multiple definitions in different translation units produces undefined
behaviour according to the C standard, it is not a constraint violation.
What that means is that it is an error in the program but not one that the
compiler is required to diagnose. But it can if it wants to.

The reason for this latitude is that the linkers provided with some
platforms do diagnose, and some don't and some diagnose in specific
circumstances. These linkers may have to support languages other than C
and the C designers wanted to make the language as easy to implement as
possible i.e. work with the existing tools (like linkers) that were out
there.

In your particular example the linker can link 2 definitions of the same
object without an initialiser. But when you gave it 2 initialisers there
was a conflict which it couldn't resolve (it can't initialise to 2 values
at once) so it complained. This isn't C defined behaviour, it is just the
way the linker works but it is allowed by C. However the program is
still faulty and may well fail on some other compiler/linker.

Lawrence
Nov 14 '05 #7
>Le 17/06/2005 02:59, dans BE************* *************** **@laposte.net,
Jean-Claude Arbaut <je************ ****@laposte.ne t> a écrit:
The standard says both variables represent the same object ...

In article <BED7EF0A.4F26% je************* ***@laposte.net >
Jean-Claude Arbaut <je************ ****@laposte.ne t> wrote:About different types: the standard says the identifiers represent the same
object, however section 6.7 says

"All declarations in the same scope that refer to the same object or
function shall specify compatible types."

So same object doesn't necessarily mean same type ? (otherwise why enforce
that restriction ?). That would mean the "int c","char c" example is
allowed.


The reason for the "compatible type" wording is that things
like this are allowed:

extern int a[];
extern int a[100];

Note that these are not the *same* type. The first one is
"array of unspecified size of int", or as I prefer to write
it, "array ? of int". The second one is "array 100 of int".
These types are compatible, but not identical.

(Similar rules hold for function declarations. One can write:

int f();
int f(int, char *);

and the two types are clearly not identical, yet are compatible.
But watch out:

int g(char);
int g(c) char c; { ... }

effectively re-declares g() with a type that is *not* compatible
with the earlier declaration. I believe a diagnostic is not
required, however.)
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
Nov 14 '05 #8

Le 18/06/2005 07:00, dans d9*********@new s3.newsguy.com, «*Chris Torek*»
<no****@torek.n et> a écrit*:
The reason for the "compatible type" wording is that things
like this are allowed: [...]


That's right.

And what about "int c" "char c" in two separate files ?
I'm still not absolutely sure the standard disallows this.

Nov 14 '05 #9
On Fri, 17 Jun 2005 03:07:54 +0200, Jean-Claude Arbaut
<je************ ****@laposte.ne t> wrote:

Le 17/06/2005 02:59, dans BED7ED1D.4F22%j e************** **@laposte.net,
«*Jean-Claude Arbaut*» <je************ ****@laposte.ne t> a écrit*:
The standard allows multiple declarations, but only one initialization (see
section 6.2.2 of ISO 9899-1999). If there is no "static" or "extern"
specifier, "extern" is assumed, hence there is no problem in your program
if you initialize one of your variables or none. I think it's preferable
to explicitly use "extern", to remember there are other declarations.

See 6.9.2 also. The standard allows one _definition_ of an object (or
function) name with external linkage and multiple declarations that
refer to it. A declaration with an initializer is always a definition.
A declaration with no initializer and 'extern' is only a declaration.
An object declaration with no initializer and no storage-class
specifier is a 'tentative definition' which magically is turned into a
definition with value zero unless overridden by a definite definition
in the same translation unit which is of course also a definition. And
doing either of those in more than one t.u. is Undefined Behavior.
(This particular U.B. is caught by *some* implementations .)

For functions it is simpler because the syntax differs. A declaration
with just a semicolon is just a declaration; something that looks
syntactically like a declaration followed by a braced block aka
compound statement is a definition. 'extern' is always redundant,
though some people consider it good style.
The standard says both variables represent the same object, and in practice,
they share data in memory. I don't know if the standard
allows you use different types (say, "int c" and "char c" in different
files), but at least it works in my version of gcc, and both variables
share the same space, again.


About different types: the standard says the identifiers represent the same
object, however section 6.7 says

"All declarations in the same scope that refer to the same object or
function shall specify compatible types."

So same object doesn't necessarily mean same type ? (otherwise why enforce
that restriction ?). That would mean the "int c","char c" example is
allowed.


Scope only applies within a translation unit (preprocessed source
file), and automatic variables may not be redeclared within the same
scope at all, so this actually applies only to multiple declarations
at file-scope of a variable or function -- or multiple declarations of
an 'extern' variable within a block, which is pretty obscure and
usually considered bad style. Yes that variable or function always has
the same type; that's precisely why the declarations must be
compatible -- and since 6.7p4 is a constraint, if your code violates
it the compiler must issue a diagnostic. Compatible, rather than
identical, allows some of the declarations to _omit_ some information:
int a[20];
int a[10]; // ERROR: incompatible
int a[]; // compatible
void f (); // old-style doesn't specify parameters
void f (int a, char * b); // compatible
int f (); // ERROR: incompatible

This may not seem useful because one doesn't normally think of just
writing more than one declaration for the same thing. There are two
places it is, though. First, pretty rare, is if there is a dependency
cycle in initializers so that you must declare some object and use it
before you can write its initializer. The other, much more common, is
when you have a header file that declares the functions and (possibly)
objects "exported" from a module for use by other t.u.s. Since a
definition is also a declaration, if you #include that header
(typically .h) into the source file that implements those entities
(.c) then the compiler will warn you of any mistakes where an object
or a prototyped function does not agree with the promised interface.

What applies between t.u.s is linkage. If a given name is declared in
different t.u.s with external linkage, both/all declarations (and the
code using them) refer to the same object or function. If an object X
actually has (is defined with) type A, but you access it through an
lvalue having an incompatible type B (from a wrong declaration) it is
Undefined Behavior (which is not required to be and rarely is
diagnosed) except for a few special cases in 6.5p7 and 6.5.2.3p5. And
even for those (former) it is possible that the stored representations
for some values of type A may be trap representations for type B and
fetching such also causes Undefined Behavior. But if B is unsigned
char, or plain char on a system where (as on many) that is unsigned,
*that* access is safe -- although it may or may not be useful.

- David.Thompson1 at worldnet.att.ne t
Nov 15 '05 #10

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

Similar topics

3
17962
by: prettysmurfed | last post by:
Hi all I have this, probably stupid question, how to avoid multiple definitions when a header file is included more than once. I thought, when you wrote the header-file and used the ifndef/define directives, the code between the statements define and endif was only compiled once. But this seems to be incorrect, as I get a whole bunch of errors when I compile the critter. For example if I include header.h more than once the
7
1931
by: Ittay Dror | last post by:
Hi I have this peculiar situation. I have a library of utility classes, which I use to compile a binary. I want to reimplement a method in class. The class is only a collection of static methods. So I copy the source and header files to another place, change the include path so this location will precede the location of the headers of the library, change the method (details after) and compile.
2
1764
by: Martin Magnusson | last post by:
I have a problem with multiple definitions that I can't quite straighten out. I have a templated class defined inside a namespace, and I want to create a function in that namespace that works on a specific instance of the templated class. Like this: // file Numerical.hpp:
5
2466
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 variable for the multiple definitions. C++, however, does not permit redefinition of a variable or any other entity for a very definite reason that we will discuss later." Chapter 1. C++ Tutorial. Coronado Enterprises Charles L
4
30437
by: Andrew | last post by:
Hello, I am recieving a multiple definition error from the linker when I try to build a project I am working on. The message states that the functions I defined within an external .c source file are already defined in the main program .obj file. I declared the functions in seperate header files and used the pre-processor conditional #ifndef FILE_H to make sure each header is only included once. Each .c source file includes the...
8
3294
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 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...
0
8385
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
8303
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 effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
8821
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, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
8723
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
8502
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 Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
1
6162
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 presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
4300
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
2726
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
1601
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

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.