Really bizarre linking error!

B

bajichuan

Hello! I have the world's strangest linking error, and I'm hoping that
someone can help me sort it out. I recently installed and compiled a
library called LinBox without a problem. I have an object-oriented
software application, and I want it to call the library. When I add
the following 3 lines (copied directly from the library tutorial),

#include <linbox/field/modular.h>
using namespace LinBox;
typedef Modular<short> Field;

to a .cpp file, my code compiles perfectly. However, when I add the
same 3 lines to a .h file (where they *must* ultimately go), I get
(among others) the following error:

/tmp/cckvjpY5.o: In function `~edge':/usr/include/gmp.h:1590: multiple
definition of
`LinBox::ModularBase<Integer>::write(std::basic_ostream<char,
std::char_traits<char> >&) const'

Comments? This is incredibly strange to me. It looks like some sort of
linking error. Namespace conflict? I don't have root access on the
school machines, and so I have compiled and am pointing to a local
copy of the LinBox library. This is so strange... why does the code
work from
the .cpp file but not the .h file?

I hope this is an error in my code and not in the library itself.
Thoughts and suggestions on how to track this down would be carefully
considered and gratefully appreciated!

Very best regards,
Susan

PS> Here is a copy of my very simple make file:

grob_heur: gc_heur.cpp Graph.cpp MonExpEnum.cpp SetCombEnum.cpp
GraphLinearSyste
m.cpp
g++ -Wall -g \
-I/LINBOX_PATH/linbox-1.1.3/include \
-I/usr/include \
-o gc_heur gc_heur.cpp \
Graph.cpp MonExpEnum.cpp SetCombEnum.cpp GraphLinearSystem.cpp
\
/LINBOX_PATH/linbox-1.1.3/linbox/util/gmp++/.libs/libgmpxx.a \
/usr/lib/libgmp.a \
/LINBOX_PATH/linbox-1.1.3/lib/liblinbox.a
 
A

Alf P. Steinbach

* (e-mail address removed):
Hello! I have the world's strangest linking error, and I'm hoping that
someone can help me sort it out. I recently installed and compiled a
library called LinBox without a problem. I have an object-oriented
software application, and I want it to call the library. When I add
the following 3 lines (copied directly from the library tutorial),

#include <linbox/field/modular.h>
using namespace LinBox;
typedef Modular<short> Field;

to a .cpp file, my code compiles perfectly. However, when I add the
same 3 lines to a .h file (where they *must* ultimately go), I get
(among others) the following error:

/tmp/cckvjpY5.o: In function `~edge':/usr/include/gmp.h:1590: multiple
definition of
`LinBox::ModularBase<Integer>::write(std::basic_ostream<char,
std::char_traits<char> >&) const'

This is not a linker error, it's a multiple definition.

That means you have defined something twice or more.

Guess what? Hint: read the error message.

Comments? This is incredibly strange to me. It looks like some sort of
linking error. Namespace conflict? I don't have root access on the
school machines, and so I have compiled and am pointing to a local
copy of the LinBox library. This is so strange... why does the code
work from
the .cpp file but not the .h file?

Because you have managed to include the header file in the same cpp file
twice, or you have included the header file in the cpp file where you
manually placed the typedef.

It may or may not be relevant to mention include guards (google).
 
A

arun.darra

Yup this is a multiple decleration problem and is completly to do with
ur program and nothing to do with the library.

there are 2 reasons for this:

1. because ur programs .h files dont have header guards
and the same header is being included multiple times.
use heade guards in ur header file, some thing like:

# ifndef _FILE_
# define _FILE_
...
the header file declerations
...
# endif

2. you have declared
typedef Modular<short> Field;
in more than one header file....

regards
Arun
 
J

Jerry Coffin

Hello! I have the world's strangest linking error, and I'm hoping that
someone can help me sort it out. I recently installed and compiled a
library called LinBox without a problem. I have an object-oriented
software application, and I want it to call the library. When I add
the following 3 lines (copied directly from the library tutorial),

#include <linbox/field/modular.h>
using namespace LinBox;
typedef Modular<short> Field;

to a .cpp file, my code compiles perfectly. However, when I add the
same 3 lines to a .h file (where they *must* ultimately go), I get
(among others) the following error:

/tmp/cckvjpY5.o: In function `~edge':/usr/include/gmp.h:1590: multiple
definition of
`LinBox::ModularBase<Integer>::write(std::basic_ostream<char,
std::char_traits<char> >&) const'

It looks like you're including the header in (at least) two different
source files (not surprising -- that's the usual reason for putting
something into a header). From the looks of things, in modular.h, you
have a _definition_ (not just a declaration) of a function named
'write' that's part of your ModularBase class. That would be all right
IF it was an inline function, but it's apparently not.

In theory, you could move it out of the header, into a source file of
its own, so no matter how many places the header was included, you'd
still have only one definition of that function.

In reality, you probably can't do that: from the looks of things, this
function is part of a template, and most compilers require that the
entirety of the template be made visible everywhere it's used. Under the
circumstances, about all you can do is make the function inline.
 
B

bajichuan

Because you have managed to include the header file in the same cpp file
twice, or you have included the header file in the cpp file where you
manually placed the typedef.

Yes, certainly that is the obvious first guess. Unfortuneatly, all of
my header files do have the traditional guards

#ifndef MY_HEADER
#define MY_HEADER

Also, all of the library files have the traditional guards as
expected. Also, as Arun suggested, I am not double declaring the
typedef, although I certainly double checked just to be sure, because
that is another obvious error.
It looks like you're including the header in (at least) two different
source files (not surprising -- that's the usual reason for putting
something into a header). From the looks of things, in modular.h, you
have a _definition_ (not just a declaration) of a function named
'write' that's part of your ModularBase class. That would be all right
IF it was an inline function, but it's apparently not.

I find this comment very interesting. Here is the function itself, as
declared within the library header file (which has guards).

template <>
std::eek:stream& ModularBase<Integer>::write (std::eek:stream &os)
const
{ return os << "GMP integers mod " << _modulus; }

Obviously, if I comment out this function within the library header
file, the code compiles fine, but of course that is not the right
solution AT ALL. Does this function declaration look okay? I think
this is a function definition, not a declaration. Isn't it also
inline? A shouldn't the guards around the header file in the library
prevent any double declaration?

Thanks for your comments!

Susan
 
I

Ian Collins

(e-mail address removed) wrote:

Please don't snip attributions, it is considered rude.
I find this comment very interesting. Here is the function itself, as
declared within the library header file (which has guards).

template <>
std::eek:stream& ModularBase<Integer>::write (std::eek:stream &os)
const
{ return os << "GMP integers mod " << _modulus; }

Obviously, if I comment out this function within the library header
file, the code compiles fine, but of course that is not the right
solution AT ALL. Does this function declaration look okay? I think
this is a function definition, not a declaration.

It is.
Isn't it also inline?

No, only class member functions defined inline have inline linkage, not
normal functions.

Your original linker error shows that this function is not declared as
inline and is should be.
A shouldn't the guards around the header file in the library
prevent any double declaration?
They can't.
 
J

Jerry Coffin

[ ... ]
I find this comment very interesting. Here is the function itself, as
declared within the library header file (which has guards).

template <>
std::eek:stream& ModularBase<Integer>::write (std::eek:stream &os)
const
{ return os << "GMP integers mod " << _modulus; }

No -- to be inline, it has to either be written inside of the class
definition, or else explicitly defined as 'inline'. You haven't shown us
the remainder of the class definition to be absolutely certain, but
qualifying the name (i.e. using "ModularBase<Integer>::write" instead of
just "write") suggests that this function is being defined outside of
the class definition.
Obviously, if I comment out this function within the library header
file, the code compiles fine, but of course that is not the right
solution AT ALL. Does this function declaration look okay? I think
this is a function definition, not a declaration. Isn't it also
inline? A shouldn't the guards around the header file in the library
prevent any double declaration?

No -- they prevent it from being declared twice in the same translation
unit (pre-processed source file). It still attempts to define the
function once in each source file where you include the header -- but
unless it's inline, you can only define it once across all the source
files that make up the complete program.
 
A

Alf P. Steinbach

* Alf P. Steinbach:
* (e-mail address removed):

This is not a linker error, it's a multiple definition.

Multiple definition yes, but I was wrong about this not being a linker
error: Jerry Coffin (else-thread) was right.

That means you have defined something twice or more.

Guess what? Hint: read the error message.

As Jerry noted, that function definition should be declared "inline" (or
moved out of the header).

It's rare that a 3rd party library header has such fundamental error.

So I didn't think of it.
 
B

bajichuan

Making the function inline did the trick!!!! Thank you so much. I will
let the people who put out the library know about the error.

Thanks again for your help and comments!

Best,
Susan
 
J

Jack Klein

On Sun, 05 Aug 2007 18:58:19 -0000, "(e-mail address removed)"

Why are you top posting? Did you not read the signature block in
Alf's post that explains why it is wrong?
Yup this is a multiple decleration problem and is completly to do with
ur program and nothing to do with the library.

Why do you refer to ur's program, when the original poster's name was
"arun.darra", and the post you replied to was from "Alf P. Steinbach"?
Did you reply to the wrong post by mistake? Actually, since you seem
to be implying that Alf's code is incorrect, even though he is not the
one who posted it, you are replying to the wrong post.
there are 2 reasons for this:

1. because ur programs .h files dont have header guards
and the same header is being included multiple times.
use heade guards in ur header file, some thing like:

# ifndef _FILE_
# define _FILE_

This, of course, is completely wrong because it violates a namespace
reserved for the implementation. All identifiers beginning with an
underscore followed by an upper case letter, and all identifiers
containing two consecutive underscores anywhere within them, are
reserved in all contexts.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.club.cc.cmu.edu/~ajo/docs/FAQ-acllc.html
 
A

arun.darra

This, of course, is completely wrong because it violates a namespace
reserved for the implementation. All identifiers beginning with an
underscore followed by an upper case letter, and all identifiers
containing two consecutive underscores anywhere within them, are
reserved in all contexts.

Well thanks for the info Jack but the idea was show the usage of
header guards... But the point u put across was well taken.. thanks.
 
B

bhadorn

Hello! I have the world's strangest linking error, and I'm hoping that
someone can help me sort it out. I recently installed and compiled a
library called LinBox without a problem. I have an object-oriented
software application, and I want it to call the library. When I add
the following 3 lines (copied directly from the library tutorial),

#include <linbox/field/modular.h>
using namespace LinBox;
typedef Modular<short> Field;

to a .cpp file, my code compiles perfectly. However, when I add the
same 3 lines to a .h file (where they *must* ultimately go), I get
(among others) the following error:

/tmp/cckvjpY5.o: In function `~edge':/usr/include/gmp.h:1590: multiple
definition of
`LinBox::ModularBase<Integer>::write(std::basic_ostream<char,
std::char_traits<char> >&) const'

Hi,
I've got the same linking error not using "inline". See

http://www.xatlantis.ch/cpp_blog/compiler.html

wbr

bhadorn
 

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

Similar Threads


Members online

No members online now.

Forum statistics

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

Latest Threads

Top