"ld: duplicate symbol" Error in Terminal HELP!

Discussion in 'Mac Programming' started by ScKaSx, Feb 3, 2010.

  1. ScKaSx macrumors regular

    Joined:
    Feb 27, 2006
    #1
    Hi All,

    I have very simple code. Consists of a main.cc and func.cc. The files compile fine, but when I link them (g++ main.cc func.cc -o prog) I get the following error:

    ld: duplicate symbol _R in main.o and func.o
    collect2: ld returned 1 exit status
    make: *** [main] Error 1

    Both files depend on and include a header file (#include "header.h"). The files are self explanatory, in my main.cc I have the main function that calls several subroutines from func.cc. When I appened the functions from func.cc at the end of main.cc and just run (g++ main.cc -o prog) it compiles, links and runs fine! Can anyone allude to what is going on here?

    Cheers, ScKaSx
     
  2. lee1210 macrumors 68040

    lee1210

    Joined:
    Jan 10, 2005
    Location:
    Dallas, TX
  3. ScKaSx thread starter macrumors regular

    Joined:
    Feb 27, 2006
    #3
    Thanks for the quick reply. Nope, I have #define, but no #ifndef's. Here is an outline of my header file:

    1 #include <math.h>
    2 #include <stdio.h>
    3 #include <stdlib.h>
    4 #include <iostream>
    5 #include <complex>
    .
    .
    .
    13 #define PRINT printf
    14 #define Cmplx complex<double>
    15 #define _i Cmplx(0.,1.)
    16 #define PI 3.14
    17
    18 using namespace std;
    19
    .
    .
    .
    25 int const=1;
    26 double c2=2.;
    .
    .
    .
    30 Func(arg, arg, arg);
     
  4. lee1210 macrumors 68040

    lee1210

    Joined:
    Jan 10, 2005
    Location:
    Dallas, TX
    #4
    At the top of your file add:
    Code:
    #ifndef header_h
    #define header_h
    ...
    #endif
    Where ... is everything you have now.

    This prevents the compiler from including a header's text more than once during compilation. If you haven't run into this before, you must be new to the rodeo, so welcome.

    -Lee

    P.S. Man, your PI is light on significant figures. I hope your not doing anything that needs much precision.
     
  5. ScKaSx thread starter macrumors regular

    Joined:
    Feb 27, 2006
    #5
    Hi lee,

    Btw thanks for all the help. However, the ifndef's don't seem to solve the problem. I am still getting the same error. Just to be sure I only need the ifndef's around the header.h code correct?

    Cheers

    P.S. you noticed the PI :), yeah I am never that precise with things
     
  6. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #6
    My guess is that you have a defining use of R in one of your header files. Possibly something like:
    Code:
    extern int R = 5;
    
    (I'm guessing at the type; it could actually be anything.)

    You should change it so there is exactly one defining use (i.e. with the initializer), and all other uses are declaring uses (without initializer):
    Code:
    extern int R;
    
    Another possibility is a duplicate function.

    Whatever it is, it appears to be named R. So start by looking for that.
     
  7. bdavis78 macrumors newbie

    Joined:
    May 16, 2008
    #7
    I'm having a very similar error. I've got a file- structures.h that needs to be included in main.c and in structures.c for compilation, but I get a similar linking error

    ld: duplicate symbol _amino_acid_tlc in /Users/davis/Documents/covarion simulation/covarions/build/covarions.build/Debug/covarions.build/Objects-normal/x86_64/structures.o and /Users/davis/Documents/covarion simulation/covarions/build/covarions.build/Debug/covarions.build/Objects-normal/x86_64/main.o


    I have

    #ifndef structures_h
    #define structures_h
    ....
    #endif

    inside structures.h file, so I don't understand why the compiler is including the structures.h file twice. amino_acid_tla is only defined once time in structures.h.

    Any suggestions/help would be appreciated.

    Thanks
     
  8. lloyddean macrumors 6502a

    Joined:
    May 10, 2009
    Location:
    Des Moines, WA
    #8
    Move the declaration of '_amino_acid_tlc' into ONE of the two source files and then place an 'extern ' in front of the definition in "structures.h".
     
  9. racine75 macrumors newbie

    Joined:
    May 18, 2010
    #9
    Or else...

    A common mistake that raises the "ld: duplicate symbol" error is to compile the same code twice into different object (.o) files that are then linked together. An example:
    gcc -c -o foo.o foo.c
    gcc -c -o bar.o foo.c
    gcc -o foobar foo.o bar.o
    You might want to check your makefile for this kind of occurence...
     
  10. Brody38h, Aug 10, 2011
    Last edited: Aug 10, 2011

    Brody38h macrumors newbie

    Joined:
    Jan 4, 2010
    #10
    I had this same problem. This works for me if I move the 'duplicate symbol' to one of the source files, but why? I have the #ifdef logic in there, so shouldn't the header file be copied to only one of the source files at most?

    Edit: Read more about it, and now understand that it only protects within same compilation unit. Which I understand. However, why can I declare and define a const int and not have the same problem?

    Thanks
     
  11. Fastgalix macrumors newbie

    Joined:
    Aug 15, 2011
    #11
    Same problem, different code (not mine and long)

    Hi all,

    I have the same problem for a long code (difficult for me since I am not C++ fluent) the error is:
    Code:
    ld: duplicate symbol LA::NRVec<double>::operator*(LA::SparseMat<double> const&) const  in .libs/sparsemat.o and .libs/vec.o
    
    sparsemat and vec mutually include each other of course :p

    Since the code is several thousands of lines I did
    Code:
    grep 'operator\*' vec.* sparsemat.*
    
    and here is the output
    Code:
    vec.h:  inline NRVec& operator*=(const NRVec &rhs);
    vec.h:  inline NRVec& operator*=(const T &a);
    vec.h:  inline const NRVec operator*(const T &a) const;
    vec.h:  inline const T operator*(const NRVec &rhs) const;
    vec.h:  const NRVec operator*(const NRMat<T> &mat) const {
    vec.h:  const NRVec operator*(const NRSMat<T> &mat) const {
    vec.h:  const NRVec operator*(const SparseMat<T> &mat) const {
    vec.h:inline NRVec<T>& NRVec<T>::operator*=(const NRVec<T>& rhs) {
    vec.h:inline NRVec<T> & NRVec<T>::operator*=(const T &a) {
    vec.h:inline const T NRVec<T>::operator*(const NRVec<T> &rhs) const {
    vec.h:inline NRVec<double>& NRVec<double>::operator*=(const double &a) {
    vec.h:inline NRVec<complex<double> >& NRVec<complex<double> >::operator*=(const complex<double> &a) {
    vec.h:inline const double NRVec<double>::operator*(const NRVec<double> &rhs) const {
    vec.h:inline const complex<double> NRVec<complex<double> >::operator*(const NRVec< complex<double> > &rhs) const {
    Binary file vec.o matches
    sparsemat.cc:unsigned int SparseMat<T>::sort(int type) const //must be const since used from operator*
                       //which must be const to be compatible with
                       //other stuff, dirty casts here
    sparsemat.cc:SparseMat<T> & SparseMat<T>::operator*=(const T &a) 
    sparsemat.cc:if(!count) laerror("operator*= on undefined lhs");
    sparsemat.cc:const SparseMat<T> SparseMat<T>::operator*(const SparseMat<T> &rhs) const
    sparsemat.cc:template SparseMat<T> & SparseMat<T>::operator*=(const T &a); \
    sparsemat.cc:template const NRVec<T> NRVec<T>::operator*(const SparseMat<T> &mat) const; \
    sparsemat.cc:template const SparseMat<T> SparseMat<T>::operator*(const SparseMat<T> &rhs) const; \
    sparsemat.h:                matel<T> & operator*() const {return *p;}
    sparsemat.h:        SparseMat & operator*=(const T &a);         //multiply by a scalar
    sparsemat.h:        inline const SparseMat operator*(const T &rhs) const {return SparseMat(*this) *= rhs;}
    sparsemat.h:  inline const NRVec<T> operator*(const NRVec<T> &rhs) const; // SparseMat * Vec 
    sparsemat.h:  inline const NRMat<T> operator*(const NRMat<T> &rhs) const; // SparseMat * Mat 
    sparsemat.h:  const SparseMat operator*(const SparseMat &rhs) const; 
    sparsemat.h:inline const NRVec<T> SparseMat<T>::operator*(const NRVec<T> &rhs) const
    sparsemat.h:inline const NRMat<T> SparseMat<T>::operator*(const NRMat<T> &rhs) const
    Binary file sparsemat.o matches
    
    Can you help me on what I should remove/comment or even if I am really not looking at the correct part of the code ?

    Thanks a lot
     

Share This Page