0

I have two headers.

// header1.h
class A
{
public:
    void f();
};

// header2.h
#include "header1.h"
inline void A::f()
{
    std::cout << "Yahoo.";
}

// test1.cpp
#include "header1.h"
int main() { A a; a.f(); return 0; }

// test2.cpp
#include "header2.h"
void ff() { /* do nothing */ }

I got a link error on MSVC 2013. I only got one translation unit, so I think that maybe "ODR" is not the reason?

Now I have test2.cpp to include header2.h. So I think that linker can find header2.h now. But still link error, why?

Huang-zh
  • 147
  • 8
  • 1
    The rule is "An inline function shall be defined in every translation unit in which it is odr-used." `A::f()` is not defined in `test.cpp` since it doesn't include `header2.h`. – T.C. Jul 24 '14 at 15:41
  • And how do you expect the compiler to even know anything about the existence of `header2.h`??? It is not included or mentioned anywhere in your code. With the very same degree of success, you could have placed your function definition into an email message and sent it to Zanzibar. – AnT stands with Russia Jul 24 '14 at 15:46
  • @AndreyT I add a file include header2.h, still error... – Huang-zh Jul 24 '14 at 15:55

2 Answers2

3

That's not how you do it with inline function. In the test.cpp file, how would the compiler even know that the function A::f is marked inline?

If you want an inline member function, you have to define it in the same header file, or include the header file where it's defined.

So solution one: #include "header2.h" instead of "header1.h".

Solution two: Define the function inline inside the class:

class A
{
public:
    void f() { ... }
};

Solution three: Define the function after the class but in the same header file:

class A { ... };

inline void A::f() { ... }
Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • So compiler think that A::f() is undefined? – Huang-zh Jul 24 '14 at 15:42
  • @Huang-zh The *compiler* don't know, or even care. The *linker* needs to know that all symbols are defined, and since no [translation unit](http://en.wikipedia.org/wiki/Translation_unit_%28programming%29) (i.e. source file) defines the `A::f` function you will get an undefined symbol error from the linker. – Some programmer dude Jul 24 '14 at 15:43
  • I add a file to include header2.h, got one translation unit defining A::f(maybe?).But still error... – Huang-zh Jul 24 '14 at 15:57
  • @Huang-zh Yes, because inline functions are defined only in the translation unit they are defined in. Include the header file in the main source file instead. Or define it in the main header file. – Some programmer dude Jul 24 '14 at 15:59
0

Your compiler doesn't know where to find A::f() because you've never told it where to look. You need to #include "header2.h" in test.cpp. Either that, or move the definition of A::f() into header1.h.

wolfPack88
  • 4,163
  • 4
  • 32
  • 47