Linkage of sections from multiple obj files

T

The Architect

Hi,

If I have the same symbol in the .data section of 2 obj files, LD
gives a multiple declaration error on linking? Would like to know the
reason for this (diab only issues a warning)

Also what if the symbols were in any other section (.rdata or .text)?
Or which sections of obj files can be merged even if they have
overlapping symbol names?

TIA!
 
J

Juha Nieminen

The said:
If I have the same symbol in the .data section of 2 obj files, LD
gives a multiple declaration error on linking? Would like to know the
reason for this (diab only issues a warning)

You have implemented the same function or global variable (or a
variable inside a namespace) in more than one compilation unit.

If the same function must appear in more than one compilation unit
(for example because it's implemented in a header file) you have to make
that function 'inline' (with that keyword). That will tell the linker
that it's ok if it appears in more than one object file. (Template
functions are implicitly inline.)

As for the variables, only one global instance must exist. Either
rename the variables in the different compilation units to avoid the
name collision, or if all of them must refer to the *same* global
variable, declare it 'extern' in all but one of the compilation units.
(Although we don't use global variables, do we?)

If none of this applies to your case, then perhaps you have some kind
of problem with project dependencies? Try rebuilding everything.
 
T

The Architect

I would *guess* is that LD is not designed to handle multiple
definitions of the same symbol. BTW, that is what the C++ language
Standard also requires: one and only one definition of any symbol in
your program. So, your linker seems to be enforcing the ODR.


The term "section" is not defined by the language Standard.


That's seems like a question you need to ask in the compiler- or
platform-specific newsgroup.

V

Ok.
Thanks for all the insights.
I did manage to resolve the problem by making it const (the symbol
moved to the .rdata section). Was curious as to how the linker behaved
with this change.
Have posted this in the GCC group.
 
J

James Kanze

I would *guess* is that LD is not designed to handle multiple
definitions of the same symbol. BTW, that is what the C++ language
Standard also requires: one and only one definition of any symbol in
your program. So, your linker seems to be enforcing the ODR.

Only very, very partially. It probably won't complain if he has
`extern double x;' in once module, and `int x;' in another.
The term "section" is not defined by the language Standard.

And the usual word for them is "segment":).

Classically, a linker will expect that there is one, and only
one, definition for each symbol, regardless of the segment it's
in. Most linkers also support other conventions as well,
depending on how the symbol is declared in the object file
(which, of course, is up to the compiler): support for Fortran's
common data or for multiple template instantiations (usually by
means of weak references) comes to mind. (Some early C
compilers declared each global variable as if it were a Fortran
common data; this isn't conform with the standard, however.)
That's seems like a question you need to ask in the compiler-
or platform-specific newsgroup.

While this isn't really the place for such questions, there is a
lot of commonality in how linkers work---comp.compilers might be
an acceptable place. (I would suggest a good book about linking
first, but I don't know of one off hand.)
 
J

James Kanze

I did manage to resolve the problem by making it const (the
symbol moved to the .rdata section). Was curious as to how the
linker behaved with this change.

Don't confuse what the compiler and linker are doing with what
you do in your C++ code to trigger this behavior. In C++, a
const variable at namespace scope has internal linkage by
default, a non-const variable at namespace scope has external
linkage by default. At the C++ level, you've changed the
linkage.

If the variable is in a header file, you've changed the number
of instances of it: with internal linkage, you have one instance
per translation unit; with external, you have one instance in
all.

As to what the compiler does with it: with external linkage, if
the declaration is a definition, the compiler generates extra
information for the linker, telling it that the symbol is
globally defined; normally, this will result in an error if
there are duplicate definitions. With internal linkage, the
compiler doesn't generate this information---as far as the
linker is concerned, the symbol doesn't exist. The segment
where the object corresponding to the symbol is irrelevant here.
 
K

kwikius

> (I would suggest a good book about linking
first, but I don't know of one off hand.)

Linkers and Loaders by John R. Levine

Nice quote from the Preface

"All the linker writers in the world could probably fit in one room and half
of them have already because they reviewed the manuscript " . (Slight
misquote but nice effect ).

regards
Andy Little
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top