Linker fails due to duplicate symbol
Using the code below, when I try to compile
clang++ -std=c++11 -stdlib=libc++ -o test sales_function.cpp sales_prog.cpp
I get the following error
duplicate symbol __ZN10Sales_data7combineERKS_ in:
/var/folders/7f/9r4z5bs90bjfm3dy1k_g03xc0000gn/T/sales_functions-5G1FRA.o
/var/folders/7f/9r4z5bs90bjfm3dy1k_g03xc0000gn/T/sales_prog-82wDRv.o
ld: 1 duplicate symbol for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see
invocation)
Now to get the non member functions in the file sales_functions.cpp to
work, I included the "sales_dat.h" header since struct Sales_data that the
functions uses is defined there. In that file though, I have the non
member function 'read', that is called in one of the constructors of the
struct Sales_data. So to circumvent that I forward declared struct and
declared the read function before the struct definition in sales_dat.h.
I've been trying different things like putting the definition of struct in
it's own file and putting the declaration only in the header file. But
that gave me other problems where the compiler couldn't use it's objects
in my non member function file.
That error I get, but I don't understand why I get the above error. I'm
thinking maybe it has something to do with "sales_dat.h" header being in
both sales_prog.cpp and sales_function.cpp but it seems like I had to put
it in sales_function.cpp in order for the non member function to use the
struct Sales_data objects.
What exactly is going on here? sales_functions.cpp
#include <iostream>
#include "sales_dat.h"
std::istream &read(std::istream &is, Sales_data &item)
{
double price = 0;
is >> item.bookName >> item.books_sold >> price;
item.revenue = price * item.books_sold;
return is;
}
std::ostream &print(std::ostream &os, Sales_data &item)
{
os << item.isbn() << " " << item.books_sold << " " << item.revenue;
return os;
}
Sales_data add(const Sales_data &lhs, const Sales_data &rhs)
{
Sales_data sum = lhs;
sum.combine(rhs);
return sum;
}
sales_dat.h
#ifndef SALES_DAT_H
#define SALES_DAT_H
#include <iostream>
#include <string>
struct Sales_data;
std::istream &read(std::istream &, Sales_data &);
struct Sales_data {
std::string bookName;
std::string isbn() const { return bookName; }
Sales_data &combine(const Sales_data &);
unsigned books_available = 10;
unsigned books_sold = 0;
double revenue = 0;
unsigned total_sold = 0;
unsigned count = 1;
Sales_data() = default;
Sales_data(unsigned c) : count(c) {}
Sales_data(const std::string &s) : bookName(s) {}
Sales_data(const std::string &s, unsigned m, unsigned n, double p) :
bookName(s), books_sold(m), books_available(n), revenue(p*m) {}
Sales_data(std::istream &inpst) { read(inpst, *this); }
};
std::ostream &print(std::ostream &, Sales_data &);
Sales_data add(const Sales_data &, const Sales_data &);
Sales_data &Sales_data::combine(const Sales_data &rs)
{
count += rs.count;
books_sold += rs.books_sold;
revenue += rs.revenue;
return *this;
}
No comments:
Post a Comment