4

I'm using multiple C++ files in one project for the first time. Both have need to include a protected (#ifndef) header file. However, when I do that, I get a multiple definition error.

What I have is two one .cpp file that calls the header directly, and one indirectly (Another include includes it) and then two other header files that include it.

So what do I need to do to get rid of the error?

ERROR:

obj\Debug\main.o||In function Z14sortLibQtyTest4BookS_':| [PATH]\miscFuncs.h|16|multiple definition ofsortLibQtyTest(Book, Book)'

CODE:

bool sortLibQtyTest(Book a, Book b){ return a.getQty() > b.getQty(); }

It should be mentioned that this isn't the only function giving me problems, probably more than ten are, and some aren't so short and sweet. Also, the functions are needed in multiple files.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
David
  • 4,744
  • 5
  • 33
  • 64

3 Answers3

5

You have two options to solve this multiple definition problem: Mark the method inline, or put the definition in a .cpp file.

1) Mark the method inline:

// Foo.h

inline bool foo(int i) { return i = 42; }

2) Put the definition in a .cpp file:

// Foo.h

inline bool foo(int i); // declaration

// Foo.cpp
bool foo(int i) { return i = 42; } // definition

Whether the method is actually inlined by the compiler in the first case is irrelevant here: inline allows you to define a non-member function in a header file without breaking the one definition rule.

juanchopanza
  • 223,364
  • 34
  • 402
  • 480
  • For anybody else reading this, this is the most concise and simple answer. For a better understanding, read the comments on the other posts. – David Jul 15 '13 at 05:24
3

The ".cpp" and ".h" suffixes are largely a matter of convention. As far as the compiler is concerned, where a line of code came from is irrelevant. When you #include that function into your .cpp files, you are implementing that function in that .cpp file.

So when the compiler is done and it asks the linker to knit together the code from your two cpp files, it finds a conflict: two functions with the same name and fingerprint (arguments and return). This is an error.

You need to either:

a. Put the implementation in one source file, and just leave a prototype declaration in the header

// .h
extern bool sortLibQtyTest(Book a, Book b);

// file1.cpp
bool sortLibQtyTest(Book a, Book b) { /* implementation */ }

b. Mark the function as inline: when you call the function, the compiler will insert copies of the function body as needed which can be wasteful, but often times the compiler can figure out the efficient thing to do.

inline bool sortLibQtyTest(Book a, Book b) { return a.getQty() < b.getQty(); }

c. Mark the function as "static" which tells the compiler to create a copy of the function for every source file that includes it, but not to expose it to the linker. If some source files include the header without using the function, the compiler has to detect this and remove it - which not all compilers/optimization levels do, so it can be doubly wasteful.

static bool sortLibQtyTest(Book a, Book b) {return a.getQty() < b.getQty(); }

d. Avoid the downsides of c, mark it static inline

static inline bool sortLibQtyTest(Book a, Book b) { return a.getQty() < b.getQty(); }
kfsone
  • 23,617
  • 2
  • 42
  • 74
1

If the Line you quoted after "CODE" is in a header file you can either:

  • add inline to the definition or
  • remove the function body from the header and put it into 1 (and only 1) of your source files.
Pixelchemist
  • 24,090
  • 7
  • 47
  • 71
  • I see what you mean, but that's not the only one that has the problem, and the others aren't so short to use inline. Also, they're needed in multiple files, which is why they're in a separate header. I just added that to my original post. – David Jul 15 '13 at 04:54
  • 1
    @David The `inline` specifier doesn't *force* inlining. If it can't inline it, then it won't. Then its only purpose at that point is to avoid multiple definition errors. – Rapptz Jul 15 '13 at 04:56
  • 1
    @David you just have to pick one of those two options. It sounds like the second option is the better one. – juanchopanza Jul 15 '13 at 04:57
  • @Rapptz What determines whether or not it can inline it? As I understand, inline tells the compiler to "copy/paste" the function code to where it's called, which can cause large delays and larger files. – David Jul 15 '13 at 04:58
  • @juanchopanza I've read about an extern method, but I can't figure out how to make it work. If inline is the way to go, then I'll do it, but then how do I determine whether a function should be inline or not, before I'm hit with errors? And how does it work? – David Jul 15 '13 at 05:00
  • 1
    @David That is implementation dependant. Not all compilers are the same, likewise compilers have certain ways to force inlining if you need it. The `inline` keyword alone won't do it since it's a hint. – Rapptz Jul 15 '13 at 05:01
  • 1
    @David as I said, I think the second option, i.e. putting the function definitions in a `.cpp` file, might be better if your functions are not trivial. But both solutions would solve the problem. – juanchopanza Jul 15 '13 at 05:03
  • @Rapptz then how do I determine what to inline? Anything an everything? Or just when I get an error, or what? – David Jul 15 '13 at 05:03
  • 1
    @David, Putting `inline` makes little difference to whether it's actually inlined. Compilers can decide for themselves whether to inline them. You should follow my first comment to your question for when to put the keyword there. Without it, each translation unit gets its own definition, all the exact same, which I believe is UB. – chris Jul 15 '13 at 05:04
  • @chris One of the files is my personal library. Should I make everything in it inline, until the class I'm in reaches namespaces. (I know about some of the advanced methods, but the class is a level one, so I've been trying to not jump to far ahead.) – David Jul 15 '13 at 05:10
  • 2
    You should definitely read a book (or any proper online resource) on C++ basics including the difference between declaration and definition and the way to use headers and source files. The "common way" is to declare things in header files (no function bodies) and define (the function bodies) in an associated source file. – Pixelchemist Jul 15 '13 at 05:14
  • @Pixelchemist any recommendations? – David Jul 15 '13 at 05:16
  • @David, Putting them in a namespace will make no difference in regards to the linking issues. And http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list – chris Jul 15 '13 at 05:28
  • @David chris has given the "definitive list" [I like the style Stroustrup writes but that's just my opinion]. ;) – Pixelchemist Jul 15 '13 at 05:34