   C++ inline syntax
  I'm making some of a class's member functions inline and I have a question about the proper syntax. What I'm doing is essentially this:// myclass.hclass myClass{public:inline const int f1();};// myclass.cppinline const int f1(){// stuff}Everything compiles, links, and runs properly. Is it any faster? Beats me. But if works.However I came across this, saying:Quote:When you declare an inline member function, it looks just like a normal member function: class Fred { public:   void f(int i, char c); };But when you define an inline member function, you prepend the member function's definition with the keyword inline, and you put the definition into a header file: inline void Fred::f(int i, char c) {   ... }It's usually imperative that the function's definition (the part between the {...}) be placed in a header file. If you put the inline function's definition into a .cpp file, and if it is called from some other .cpp file, you'll get an "unresolved external" error from the linker. This raises two questions:1. Should I remove the inline from the declaration? I'm thinking I'm going to simply to make the code easier to maintain, and if the way I'm doing it now is excessive, why not.2. I don't appear to have the linking problem described above. I have the definitions in a .cpp yet I can use the inline functions wherever I please, in other classes even. So am I reading the above incorrectly, did the C++ standard change, is this a peculiarity of my compiler, did my use of the keyword "inline" in the header spare me from this fate, or is it something completely different?Thanks in advance![Edited by - CyberSlag5k on June 3, 2006 1:41:10 PM]
  You will get lots of long winded replies, but the short version is, inline does frig all and as proven by Herb Sutter is actually useless in some situations.Only be concerned with it when u have performance issues and even then it is unlikely to provide anything.Dave   ;  The compiler will most times optimize this for you.  I have a general rule of making a <= 5 line function inline and otherwise let the compiler sort it out.   ;  I think inlining has pretty much nothing to to with the number of line of your function.- The first reason is that 5 lines of code can generate more assembly than 50 lines.- The second reason is that even if your function is 5 lines of code, if it gets called a a lot of places, inlining may result in you executable size to increase. And you might end up with a loss of speed.So, good candidtes for inlining are function which you call a lot of time per second but in few places in your code. It's true that you most often have to put you function code in the header file, since most compilers arent able to do function inlining at link time. Thus the code has to be known at compile time. If you want to keep a good organization, I suggest you never ever put some code into the .h directly. You could create a .hpp file that will hold all your function definition and include that .hpp in you .h (and nowhere else)Often, some people are reluctant to inline function because they think they have to be defined diretly it the class declaration like:class MyClass{    inline void myMethod()    {   // some stuff    }}of course when "some stuff is 10+ lines, it can make you class declaration badly unreadable. Plus, when declaring and defining you function directly like the above, inline is implicit (this might be microsoft-specific, Im not sure) So just do:class MyClass{    inline void myMethod();}inline void myMethod(){   // some stuff}(or use a .hpp file as I mentionned)Last but not least, "inline" is not exactly something you order to the compiler. It's rather a request that can be denied. Indeed at compile time your compiler will perform a performance/cost analysis of inlining your method, and will proceed only if it seems to be beneficial. You cant be 100% sure that your function will be inlined (with visual studio the compiler can tell you if it did, if you activate the appropriate option)Here is the MSDN doc about inline and (MS-specific) __inline, __forceinline:Quote:The insertion (called inline expansion or inlining) occurs only if the compiler's cost/benefit analysis show it to be profitable. Inline expansion alleviates the function-call overhead at the potential cost of larger code size.The __forceinline keyword overrides the cost/benefit analysis and relies on the judgment of the programmer instead. Exercise caution when using __forceinline. Indiscriminate use of __forceinline can result in larger code with only marginal performance gains or, in some cases, even performance losses (due to increased paging of a larger executable, for example). Using inline functions can make your program faster because they eliminate the overhead associated with function calls. Functions expanded inline are subject to code optimizations not available to normal functions.The compiler treats the inline expansion options and keywords as suggestions. There is no guarantee that functions will be inlined. You cannot force the compiler to inline a particular function, even with the __forceinline keyword. When compiling with /clr, the compiler will not inline a function if there are security attributes applied to the function.The inline keyword is available only in C++. The __inline and __forceinline keywords are available in both C and C++. For compatibility with previous versions, _inline is a synonym for __inline.The inline keyword tells the compiler that inline expansion is preferred. However, the compiler can create a separate instance of the function (instantiate) and create standard calling linkages instead of inserting the code inline. Two cases where this can happen are: Recursive functions.Functions that are referred to through a pointer elsewhere in the translation unit.These reasons may interfere with inlining, as may others, at the discretion of the compiler; you should not depend on the inline specifier to cause a function to be inlined.Functions that are declared as inline, and that are not class member functions, have internal linkage unless otherwise specified.As with normal functions, there is no defined order of evaluation of the arguments to an inline function. In fact, it could be different from the order in which the arguments are evaluated when passed using normal function call protocol.The /Ob compiler optimization option helps to determine whether inline function expansion actually occurs./LTCG performs cross-module inlining regardless of whether it was requested in source code.Janta   ;  Thanks guys. I'm pretty familiar with the implications (and likely insignificances) of using inline functions, though it's good to hear others' thoughts on the practice, and Janta's post in particular was very informative. However I'm merely concerned with whether or not I am in error with respect to how I've defined my functions in that second file. Everything runs smoothly on my system, but if this is indeed an imporoper way to do it, I'd like to know if I need to fix it lest things link improperly on another system. Even better, though, would be if someone were to tell me that I need not worry about it because the FAQ I read is outdated or my declaration of the functions alleviates said concerns. If it is not so, however, I rather like your .hpp suggestion, Janta. Anyone know?EDIT:Curious. It seems everything linked properly as I was only inlining overloaded operators. As soon as I inlined a regular function, I got the linker errors. I've moved everything into a .hpp file as per Janta's suggestion (thanks again), but why would it work with an overloaded operator and not with a regular function?[Edited by - CyberSlag5k on June 3, 2006 2:09:49 PM];  Quick test:No error:// Test.hclass Test{public:void TestMethod();};// test.cpp#include "Test.h"void Test::TestMethod(){printf("Some stuff");}// main.cpp#include "Test.h"void main(){    Test t;    t.TestMethod();}error LNK2019: unresolved external symbol "public: void __thiscall Test::TestMethod(void) // Test.hclass Test{public:inline void TestMethod();};// test.cpp#include "Test.h"void Test::TestMethod(){printf("Some stuff");}// main.cpp#include "Test.h"void main(){    Test t;    t.TestMethod();}error LNK2019: unresolved external symbol "public: void __thiscall Test::TestMethod(void) // Test.hclass Test{public:void TestMethod();};// test.cpp#include "Test.h"inline void Test::TestMethod(){printf("Some stuff");}// main.cpp#include "Test.h"void main(){    Test t;    t.TestMethod();}error LNK2019: unresolved external symbol "public: void __thiscall Test::TestMethod(void) // Test.hclass Test{public:inline void TestMethod();};// test.cpp#include "Test.h"inline void Test::TestMethod(){printf("Some stuff");}// main.cpp#include "Test.h"void main(){    Test t;    t.TestMethod();}No error (everything is in the .h file)// Test.hclass Test{public:inline void TestMethod();};inline void Test::TestMethod(){printf("Some stuff");}// main.cpp#include "Test.h"void main(){    Test t;    t.TestMethod();}Do you find yourself in one of the above ?I think there is no reason that an operator overloading method will compile where a "normal" method would fail to.BTW, I use Visual C++ Express, how about you ? Results may differ if you're using something else.;Quote:Original post by DaveYou will get lots of long winded replies, but the short version is, inline does frig all and as proven by Herb Sutter is actually useless in some situations.Only be concerned with it when u have performance issues and even then it is unlikely to provide anything.That's misleading. Herb Sutter said pretty much the exact opposite - that it does have an effect, even in modern compilers.What he did say is to generally avoid it because it can actually have a negative effect. Only use it as an optimisation, and be careful that when you do use it that it is actually having a positive effect.   ;What Herb Sutter really said;  I experienced similar issues with inlining (to the original poster) under both VC++ 6sp2 and a not too horribly outdated version of g++.I had multiple member functions of the form (well, if I had just 1 or both inlines, I don't remember; position of const modifier(?): some with, some without; some actually called, some not)// myclass.hclass myClass{ public:  inline int f1() const;};----------------------// myclass.cppinline int myClass::f1() const{  // stuff}The odd thing is, some functions linked while others didn't. I eventually gave up on explicitly suggesting inlining and decided to let the compiler sort it all out.   ;  Well to specify, I have the word inline once in over 200k lines of engine code.  I let the compiler optimize for me.  Really, until a profiler says something is an issue, don't inline/whatever.  If the compiler wants too, more power to it.I could be wrong but worrying about this sort of thing until it's an issue is kinda a waste of time but that's just my opinion.Edit:@janta: Your idea about a .hpp is kinda weird, most people use that like a .h file (.c/.h, .cpp/.hpp, just some people got lazy and didn't do .hpp).  A better and more obvious idea is .inl short of inline.   