Duplicate symbol _FOO in a.o and b.o - not the usual cause in C++

144 views Asked by At

First of all, thanks for all of the great info on this site. It's always my first port of call for programming problems. Unfortunately I couldn't find none of the solutions mentioned in other posts about similar problems seemed to work.

I have am used to coding very large simulations but recently got an error that I hadn't come across before. I've reduced the code down to a matter of lines - for the sake of debugging and am stil getting the problem. That is:

When I click build (Using QTcreator and C++), I get the following error:

":: error: duplicate symbol _GENERATOR in randoms.o and main.o"

":: error: collect2: ld returned 1 exit status"

Form reading other posts I know that this tends to be the result of #include-ing things twice but I have not done this.

Here is an example of some code that generates this error:

The code consists of randoms.h, randoms.cpp and main.cpp

randoms.h:

#ifndef RANDOMS_H
#define RANDOMS_H

#include <iostream>
#include <iomanip>
#include <ctime>
#include <boost/random.hpp>
#include <stdio.h>
#include <stdlib.h>

const double price = 127.4;

boost::mt19937 GENERATOR(static_cast<unsigned> (std::time(0)));
int randIntRange(int low, int high);
double randDoubleRange(double low, double high);
void d_Range(std::vector<double> *range, double low, double high, double breaks);

#endif // RANDOMS_H

randoms.cpp:

#include"randoms.h"

int randIntRange(int low, int high) {
    boost::uniform_int<> dist(low, high);
    boost::variate_generator<boost::mt19937&, boost::uniform_int<> > range(GENERATOR, dist);
    return range();
}

double randDoubleRange(double low, double high) {
    boost::uniform_real<> dist(low, high);
    boost::variate_generator<boost::mt19937&, boost::uniform_real<> > range(GENERATOR, dist);
    return range();
}

void d_Range(std::vector<double> *range, double low, double high, double breaks) {
    double interval;
    interval = double(high - low)/double(breaks);
    for (double i=low; i < high; i+=interval) {
        range->push_back(i);
    }
}

main.cpp:

#include"randoms.h"

int main() {

    double a = 156;
    double b = 14256;
    std::cout << a << " divided by " << b << " close to " << ((a/b)*randDoubleRange(0.9,1.1)) << std::endl;

    return 0;
}

Perhaps I'm just doing something really silly but I can't figure out why anything would be duplicated. Any help would be much appreciated.

Thanks in advance

2

There are 2 answers

1
Michael Krelin - hacker On BEST ANSWER

You have this global

boost::mt19937 GENERATOR(static_cast<unsigned> (std::time(0)));

in the header file which is included in two files. That is, it is defined twice. You probably want to put the declaration in header

extern boost::mt19937 GENERATOR;

and the definition in one of the cpp files. just like you do with functions.

0
Johan Lundberg On

It's really just the case of defining the same variable twice and has nothing to do with boost. It's just like this:

hello1.cxx

int hello;

main.cxx

int hello;
int main (){return 1}

See the answer by Michael for how to deal with it.