1

I have some member functions in a class. When I use the inline specifier, the compiler complains of undefined reference.

I have tried:

Using 'inline' to precede the function definition in the class header file only.

Using 'inline' to precede the function declaration in the class .cpp (where the member functions are specified) file only.

Doing both of the above at the same time.

Obviously, one of these ways is the correct thing to do, and the others are not correct. However trying each option did not get me a program which compiled.

Here is what I am trying to do:

.hpp file:

class A{
    void func();
}

.cpp file:

... include ...

inline void A::func()
{ 
    ...
}

Or maybe 'inline' goes elsewhere. I have tried all possible combinations I could think of, as I explained above. (Now watch someone tell me I need it AFTER the function name and arguments, like the keyword 'const'.)

Anyone any ideas on what I am doing wrong? I tried googling what the correct answer might be, but no luck. Are 'inline' functions inside a class even a thing?

FreelanceConsultant
  • 13,167
  • 27
  • 115
  • 225
  • 3
    Why do you want to mark that function as `inline`? You might have the strange idea that the `inline` keyword is somehow related to the compiler inlining code... – David Rodríguez - dribeas Jul 09 '13 at 18:47
  • Is that not what inline functions are? – FreelanceConsultant Jul 09 '13 at 18:48
  • No, not really... `inline` only means that the implementation (toolset, compiler + linker) can see the same (exact same) function defined in multiple translation units and that will not cause a violation of the One Definition Rule. Other than that, whether the compiler does inline the code or generates an out of line definition is completely different, but in the general case *seeing* the definition (i.e. if it appears in the header, not the .cpp) helps. – David Rodríguez - dribeas Jul 09 '13 at 18:54

2 Answers2

8

Inline functions have to be defined in header files. The definition (the body) of the function has to be visible in all translation units that attempt to use that function. You can define it directly inside the class. Or you can define it as in your code, i.e. outside of the class. But it has to be in header file, not in .cpp file.

Attempting to define an inline function in .cpp file will make it usable in that .cpp file only. Trying to use it in other .cpp files will lead to linker errors (i.e. "undefined reference" errors).

AnT stands with Russia
  • 312,472
  • 42
  • 525
  • 765
  • 7
    @Edward Bird: No it doesn't. The "undefined reference" you are getting is exactly that: g++ disagrees with *you* and agrees with me. – AnT stands with Russia Jul 09 '13 at 18:47
  • In the header file I have a function, which I have specified to be inline. Without the inline keyword, it compiles fine. You are about to tell me this is what you expect to happen? – FreelanceConsultant Jul 09 '13 at 18:49
  • 1
    @Edward Bird: Yes, that's exactly what I'm telling you. *Non-inline* function has to be defined in one place and only in one place. This is why you normally put the definition into a `.cpp` file. But *inline* function has to be defined again and again *everywhere* (in each translation unit) where it is used. This is why inline functions are normally defined in header files. – AnT stands with Russia Jul 09 '13 at 18:51
  • In other words, you cannot flip-flop between inline and non-inline version by just adding/removing the `inline` keyword. You have to reorganize the code each time you make the switch. – AnT stands with Russia Jul 09 '13 at 18:52
  • Ah, bummer, so basically the correct answer is "this cannot be done, unless you move the body of your function code to the header file?" – FreelanceConsultant Jul 09 '13 at 18:52
  • Might have been better if you had said that instead of trying to be too clever and talking about translation units. To me that is nonsense talk. – FreelanceConsultant Jul 09 '13 at 18:57
  • 1
    @EdwardBird Seriously? Trying to explain something the correct way is *nonsense talk*? The standard talks about *translation units* and *odr-use* in conjunction with `inline`. So how is Andrey being too clever? Here's a quote (§3.2/3) *An inline function shall be defined in every translation unit in which it is odr-used.* – Praetorian Jul 09 '13 at 19:01
  • @Edward Bird: I was trying to be correct. Note that you are not the only person here. And this is exactly why trying to sacrifice correctness for simplicity often leads to significantly more heated and ugly arguments here. – AnT stands with Russia Jul 09 '13 at 19:09
1

Putting inline anything inside the CPP file can only possibly inline the function inside that file. If you want to encourage the compiler to inline the function, you need to forget about the CPP file. Instead, do this in the hpp file:

class A{
  inline void func();
};

void A::func() {...}

NB a few points:

  1. Putting inline doesn't mean your function will be inlined. It's a hint to the compiler.
  2. You need optimization (-O3 in gcc) to even have a chance at it being inlined
  3. If you define the function inside the class, it implicitly has the inline keyword on:

    class A{
      inline void func() {
        ...
      }
    };
    

    is the same as the above where it was declared inline in the class and the definition was outside.

There are ways to force GCC to inline your code using function attributes, but I will not describe them because it is rarely a good idea to use them. GCC should do the "best" thing regarding inlining for each function. Forcing it to do something else will almost always result in worse performance.

JoshG79
  • 1,685
  • 11
  • 14