I am experiencing a strange issue where attempting to inline
the accessors for my "Person" class causes the code to fail to compile.
The following code will compile and run successfully (Using Visual Studio 2012):
Person.h
#pragma once
#include <string>
using namespace std;
class Person
{
public:
Person(string name, int age = 0);
~Person(void);
// Accessors
string name(void) const;
int age (void) const;
private:
string m_name;
int m_age;
};
Person.cpp
#include "stdafx.h"
#include "Person.h"
Person::Person(string name, int age) :
m_name(name),
m_age (age )
{}
Person::~Person(void) {}
string Person::name(void) const
{
return m_name;
}
int Person::age(void) const
{
return m_age;
}
header_test.cpp
#include "stdafx.h"
#include <iostream>
#include "Person.h"
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
Person p("Joe");
cout << p.name() << endl;
return 0;
}
If I change my accessors to be defined as inline
functions the code breaks.
Inlining the accessors in Person.h
// Accessors
inline string name(void) const;
inline int age (void) const;
Inlining the accessors in Person.cpp
inline string Person::name(void) const
{
return m_name;
}
inline int Person::age(void) const
{
return m_age;
}
Doing this produces the following errors:
1>header_test.obj : error LNK2019: unresolved external symbol "public: class std::basic_string,class std::allocator > __thiscall Person::name(void)const " (?name@Person@@QBE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@XZ) referenced in function _wmain
1>fatal error LNK1120: 1 unresolved externals
God that error message is cryptic... Thank you for all of that oh so useful information Microsoft/Visual Studio!
I know the inline
keyword is just a "hint" to the compiler and probably has no real value here, but it still shouldn't break the code!
Why is this happening?
I am not a language lawyer, so I can't tell if the compiler behaviour is legitimate or not. Yet, I can explain what is happening.
When you are marking your functions inline
, you are not hinting the compiler that it can inline this function. Since over 10 years compilers do not need your hint here. They know when to inline. Instead, what you do, you indicate the function definition to be local for every translation unit it is included in. For this definition should be available.
Effectively what you said is that name()
definition should be local for every .cpp
file, but you didn't make it available for every .cpp
file! I still believe the compiler could give a warning here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With