0

Say I have two files a.cpp and b.cpp and they both use a function in c.hpp. If I #include "c.hpp" in both a.cpp and b.cpp I would get an error during linking saying the symbol has been defined twice (since header guards don't prevent inclusion across multiple translation units)

So how do I give both .cpp files access to the function in c.hpp without getting an error during linking?

dfg
  • 777
  • 1
  • 8
  • 24
  • 2
    What exactly is in `c.hpp`? Just the prototype, or also the implementation? By your edit I am assuming the full implementation. – indiv Nov 18 '14 at 21:38
  • 1
    Only put a *declaration* of the function in the header. Put the definition of the function into `c.pp`. – Jerry Coffin Nov 18 '14 at 21:39
  • The general rules is to put prototypes and class/struct definitions in your header files and put the implementation in a c/cpp file. – Retired Ninja Nov 18 '14 at 21:39
  • @JerryCoffin But I often see implementations of setter/getter functions for classes in the header. Why isn't this a problem? – dfg Nov 18 '14 at 21:40
  • You need to take care about [`header include guards`](http://stackoverflow.com/questions/1653958/why-are-ifndef-and-define-used-in-c-header-files/1653965#1653965) – πάντα ῥεῖ Nov 18 '14 at 21:40
  • @RetiredNinja But I often see implementations of setter/getter functions in the header. Why isn't this a problem? – dfg Nov 18 '14 at 21:40
  • Does the symbol correspond to a variable? If so, consider changing the design so that it isn't exposed through the header or mark it `extern`. – Void - Othman Nov 18 '14 at 21:41
  • @Void No, the symbol is a function. – dfg Nov 18 '14 at 21:42
  • 2
    Inline functions (either explicitly marked as `inline`, or defined inside a class definition) have slightly different rules, that allow multiple definitions as long as they're all identical. – Jerry Coffin Nov 18 '14 at 21:42
  • You can include implementations inside the class/struct definition in C++, or outside if you have marked them inline, but since you asked a general question tagged with two very different languages I gave a general comment. – Retired Ninja Nov 18 '14 at 21:43
  • @JerryCoffin Does the same thing apply to constructors and destructors? I see many implementations of constructors and destructors in the header. – dfg Nov 18 '14 at 21:43
  • Any member function defined inside the class definition is implicitly `inline`. – Jerry Coffin Nov 18 '14 at 21:47

2 Answers2

3

For a long function you would want to give the function it's own translation unit, moving the implementation to it's own CPP and only keeping the declaration in the header.

If the function is short you can add the inline keyword:

inline void myfunction() ...

This allows the compiler to inline the function in each translation unit, avoiding the multiple definintions.

Jay Miller
  • 2,184
  • 12
  • 11
  • Thanks. Apparently getter/setter functions can be implemented in the header without explicitly adding the inline keyword. Does the same thing apply to constructors/destructors? Can I implement them in the header without making them inline? – dfg Nov 18 '14 at 21:46
  • Any class member function defined in the class declaration is **inline** by default. Free functions (not part of a class) or member functions defined outside the class need the keyword if you want them to be interpreted this way. This is true for constructors and destructors just like any other method. – Jay Miller Nov 18 '14 at 21:49
1

In most cases the header file should contain just the declaration of the function, i.e. the function header. The function definition (the body) should be contained in a separate .cpp file. So in your case, it should look like this:

c.hpp:

int my_function(int x, int y);

c.cpp:

#include "c.hpp"

int my_function(int x, int y)
{
    return x + y;
}

and add #include "c.hpp" to any other file where you wish to use my_function. All .cpp files will be compiled separately and linker will handle the rest.

Ips
  • 369
  • 1
  • 6