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