• Some users have recently had their accounts hijacked. It seems that the now defunct EVGA forums might have compromised your password there and seems many are using the same PW here. We would suggest you UPDATE YOUR PASSWORD and TURN ON 2FA for your account here to further secure it. None of the compromised accounts had 2FA turned on.
    Once you have enabled 2FA, your account will be updated soon to show a badge, letting other members know that you use 2FA to protect your account. This should be beneficial for everyone that uses FSFT.

C++ inline issue

Wingy

[H]ard|Gawd
Joined
Dec 18, 2000
Messages
1,294
Hello,
I was working on a project when I came to an error that was bothering me. I'm using Visual Studio 2005, and the following code gives me these link errors:

1>main.obj : error LNK2019: unresolved external symbol "public: int __thiscall example::getVal(void)const " (?getVal@example@@QBEHXZ) referenced in function _main
1>C:\Documents and Settings\u0095655\My Documents\Visual Studio 2005\Projects\vaschform\Debug\vaschform.exe : fatal error LNK1120: 1 unresolved externals


example.h
#pragma once

class example
{
public:
example();
inline int getVal() const;
private:
int val;
};

example.cpp
#include "example.h"

example::example()
{
val = 10;
}

inline int example::getVal() const
{
return val;
}

main.cpp
#include <iostream>
#include "example.h"

using namespace std;

int main()
{
example e;
cout << e.getVal() << endl;

}

I want to keep the getVal() method constant in my project, so I use that here.
Now, if I remove the inline keywords, I don't get errors. If I place the class dec and def in main.cpp, I don't get the errors. What is going on here?
 
If I remember correctly you have to define inline member functions at the class declaration.

so you cannot have getVal declared in example.h and defined in example.cpp.

I am sure someone can correct me if I am wrong.

example.h
Code:
#pragma once

class example
{
public:
   example();
   inline int getVal() const
   {
      return val;
   }
private:
   int val;
};

example.cpp
Code:
#include "example.h"

example::example() : val(10)
{
}
 
If I remember correctly you have to define inline member functions at the class declaration.

so you cannot have getVal declared in example.h and defined in example.cpp.

I am sure someone can correct me if I am wrong.
Yeah; that's not quite right. Inline members can be separate from the class declaration; they just have to appear in every compilation unit where they're used. A convenient way to do this is to make them a part of the class declaration, but they can appear outside the declaration -- even in a different file, if they need to -- without a problem.
That is, this is just fine:

Code:
#pragma once

class example
{
public:
   example();
   inline int getVal() const;
private:
   int val;
};

inline int example::getVal() const
{
   return val;
}

Wingy is not providing a definition of the inline he's got in the compiland where he's using it. main.cpp, in his code, never sees the definition of example::getVar(), and since inline functions have no linkage, the linker can't find it and complains.

This is described in section 3.2.3 of the standard, and discussed in 7.1.2.
 
Im a little confused, if you can put inline function definitions in a seperate file, how do you go about doing it? I thought I had done this before, in the way I'm trying above. How would I correct this, without moving the definitions to the header file.
 
Since Mike said you'd have to provide definitions for each compiland, I assume that means:

example.hh
Code:
#pragma once

class example {
    public:
        example();
        inline int getVal() const;
    private:
        int val;
};

example.cc
Code:
#include "example.hh"

example::example() : val(10) {}

inline int example::getVal() const {
    return val;
}

main.cc
Code:
#include "example.hh"
#include <iostream>
using namespace std;

inline int example::getVal() const {
    return val;
}

int main() {
    example e;
    cout << e.getVal() << endl;
}

But, what's wrong with putting the class function definitions in the header file (as in a header-only library for example)?

Kind of like:

example.hh
Code:
#pragma once

class example {
    public:
        inline example();
        inline explicit example(const int i);
        inline int getVal() const;
        inline void setVal(const int i);
    private:
        int val;
};

inline example::example() : val(10) {}
inline example::example(const int i) : val(i) {}

inline int example::getVal() const {
    return val;
}

inline void example::setVal(const int i) {
    val = i;
}

main.cc
Code:
#include "example.hh"
#include <iostream>
using namespace std;

int main() {
    example e;
    cout << e.getVal() << endl;
    e.setVal(55);
    cout << e.getVal() << endl;
    const example x(44);
    cout << x.getVal() << endl;
}
 
Im a little confused, if you can put inline function definitions in a seperate file, how do you go about doing it? I thought I had done this before, in the way I'm trying above. How would I correct this, without moving the definitions to the header file.

Sounds like you're confusion is about the difference between a compiland and a file.

A file can be a CPP file or a H file. Several (but, at least one) files get together to make a compiland. A compiland is one run of the compiler.

In your original code, there are two compilands (again, I'm guessing -- since you've still shared nothing about your build scheme). They are example.cpp and main.cpp. example.cpp has a definition of example::getVal(), but the other compiland, main.cpp, doesn't see that definition.

I'm afraid that adding namespaces only confuses the explanation.
 
Ok, I understand then why inline would require that, by the very nature of what inline is.

Thanks for clearing that up for me everyone.
 
Back
Top