0

I defined a class in header file and implemented its function in same header file. I didn't put inline keyword with function definition because I think compiler will regard it as a inline function by default -- but inline is only a hint to compiler, right? What if compiler doesn't regard it as inline function because of its length? I never get error message 'multiple definitions' in reality.

struct tmp {
    void print() {
       ...(very long)
     }
};
Lw Cui
  • 483
  • 7
  • 15

2 Answers2

2

I didn't put inline keyword with function definition because I think compiler will regard it as a inline function by default

Yes, member functions defined in the body of a class are implicitly inline. The keyword is not necessary.

inline is only a hint to compiler, right? What if compiler doesn't regard it as inline function because of its length?

Yes, sort of. Actually, the inline keyword has two meanings.

The first one is the one you are thinking of, the one that hints to the optimizer to inline the code in the function body at the call site. As you said, this is just a hint—the optimizer is free to ignore this request if it determines that it would be a performance pessimization to do so (or if it is unable to inline for some other technical reason). This meaning of the inline keyword is arguably obsolete. All optimizing compilers nowadays ignore the inline keyword because their authors consider their heuristics to be smarter than the programmer. This is almost always the case, making it rather pointless to try and second-guess the optimizer by marking your functions inline.

The second meaning of the inline keyword is to relax the one-definition rule (ODR), making it legal for there to be multiple definitions of the same function visible to the linker. (Although the behavior of the linker under such circumstances is an implementation detail, most of them will just arbitrarily pick one of the definitions. Which of course only works out well if they are all the same.) This meaning of the inline keyword is still very important, and explains why it is still used today in code.

This is the meaning that your code is benefitting from. Since member functions defined in the body of a class are implicitly marked inline, you do not get multiply-defined symbol errors from the linker.

If you had defined the function in the header file but not within the class definition—in other words, if you had done this:

struct tmp {
    void print();
};

void tmp::print()
{ ... }

then you would start getting the multiply-defined symbol errors as soon as that header file was included in two or more compilands (i.e., translation units). This is where you would need to add the inline keyword on the function's definition, not because you want the compiler to "inline" it, but because you want to exempt yourself from the ODR.

Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574
  • So `inline` for small functions defined only once make no sense? – Lw Cui Jun 14 '16 at 12:07
  • @lw The two meanings of the `inline` keyword cannot be pulled apart quite that easily. It is not meaningful to mark a function declaration as inline unless the declaration and definition are one-in-the-same, so you cannot ever have an inline function that is defined only once. You essentially *always* have to use inline if you're defining a function in the header file (either explicitly or implicitly). That is another reason why the optimizer generally ignores inline as an optimization hint, and just does what it wants to do. Stop thinking about inline as an optimization; it just bypasses ODR. – Cody Gray - on strike Jun 14 '16 at 13:09
0

EDIT @Leon (below) stated that my answer (reproduced below) was INCORRECT. The correct answer is described here - in short, if the compiler decides to not make a function inline, it still puts it in the object module. But the linker will then pick one of the (potentially many) copies in the different modules and discard all the others.


You are right: you won't get the "multiple definition" error because every time the compiler decides to not put a function inline, it makes the function static within the current module. That means that you could have a large number of copies of your large function littered through your code.

Community
  • 1
  • 1
John Burger
  • 3,662
  • 1
  • 13
  • 23
  • 1
    That's not correct. See http://stackoverflow.com/questions/4193639/inline-function-linkage/4193698#4193698 – Leon Jun 14 '16 at 11:37
  • Wow. You learn something new every day. I knew that the `inline`ed function was in every module that it was compiled into - I didn't realise that the linker picked one and stripped all the others. – John Burger Jun 14 '16 at 11:46
  • In this question "multiple definition" error appears http://stackoverflow.com/questions/30803019/when-we-define-a-class-member-function-in-header-file-of-that-class-then-inline So I think position matters.. – Lw Cui Jun 14 '16 at 11:55