inline keyword question

Started by
11 comments, last by cavemanbob 19 years, 3 months ago
I see *lots* of people, including some very bright ones marking member functions inline when the definition is provided within the class. Supposedly, providing the member function definition within the class declaration is an implicit request for inlining. However, I'm wondering if this is one area where compilers can differ quite a bit such that it is beneficial to include the redundant inline keyword.
--God has paid us the intolerable compliment of loving us, in the deepest, most tragic, most inexorable sense.- C.S. Lewis
Advertisement
I lately made my own GZIP deflate decompressor. I wanted it to be quick, so I made some heavily-used functions inline (1st time for me). Later, when I found out that ZLIB was twice as fast anyway, I tried to make those inline functions 'normal' functions and guess what: the program became 10% faster! I guess it had something to do with the cache. So inline is not always faster, actually I haven't seen an example in which it was faster than a usual function (well it might be faster if you call that function just 1 time, but in that case: what the heck about that very small amount of overhead?)

If somebody can explain why anybody should use inline functions it would be very interesting for me :)

Bas
Inlined functions can be injected into each translation unit, removing the need for the function to be linked. That is why Boost is mainly a header-only library.
--God has paid us the intolerable compliment of loving us, in the deepest, most tragic, most inexorable sense.- C.S. Lewis
As I am using MSVC, I have heard that the only way to be sure that your regular function will be inlined is to use to __forceinline keyword. I am not sure about other compilers, but I know that with VC++, the compiler will do a cost/benifit sort of waiting to decide whether a non-member function will be inlined.

However, as far as member functions, MSDN claims that:
(this quote is in reference to the compiler switch /Ob1)
Quote:Expands only functions marked as inline or __inline or, in a C++ member function, defined within a class declaration (default with /O1, /O2, and /Ox)

From that line in MSDN, it sounds like C++ member functions are by default generated as inline functions if they are defined inside the class and used with /O1, /O2, or /Ox compiler switches.

I suppose the only way you could be sure if a function was inlined would be to look at the assembly produced.
Quote:Original post by basananas
If somebody can explain why anybody should use inline functions it would be very interesting for me :)

In the very simplest example, if you have a Object::Set_Pos(x,y); function, and the function is defined as Object::Set_Pos(x,y){ this->x=x; this->y=y; }, then there is no reason to make an entire function call when you could just easily insert the body of the function into your code. As functions get larger, you would need to weigh the cost of having a larger executable from inserting the entire body of a function into various places in your code (which can slow things down) vs the cost of a function call.
Quote:Original post by antareus
In the very simplest example, if you have a Object::Set_Pos(x,y); function, and the function is defined as Object::Set_Pos(x,y){ this->x=x; this->y=y; }, then there is no reason to make an entire function call when you could just easily insert the body of the function into your code. As functions get larger, you would need to weigh the cost of having a larger executable from inserting the entire body of a function into various places in your code (which can slow things down) vs the cost of a function call.


Ah, it's starting to make sense now... thanks.

Bas
I don't know of any modern compiler that does not treat member functions implemented in the declaration IDENTICALLY to declaring them inline below the declaration ...
antareus: Well, the boost folk don't have much choice, as just about everything in boost uses heavily templates, so the definitions must be accessible in every compilation unit that uses them.

As for the inline keyword, the compiler is allowed to completely ignore the programmer's requests if it thinks it knows better (and the modern compilers do know!). BTW, the same holds for the register keyword. This goes both ways: the compiler is also allowed to inline functions not designated inline, so in this respect the keyword is rather redundant.

Note though that if you want to define a method in a header and outside the class declaration (so that it can be inlined in different compilation units in the first place) you need to use the inline keyword to prevent linker errors.
Inline functions can be faster when passing parameters (via stack) to these functions is the bottleneck; inline functions should be interpreted from compiler as a simple copy-and-paste the code where you call an inlined function.
It is strange but an inlined function can make the code slower for different reasons (too many instructions)...moreover the compiler can ignore the directive.
My suggestion is to use inline only if the function is very very simple (for example access to a private member or something like this).

On CPP faq there are a lot of interesting tips

http://www.parashift.com/c++-faq-lite/inline-functions.html

someone wrote:

Quote:
Inlined functions can be injected into each translation unit, removing the need for the function to be linked.


Right

Quote:
That is why Boost is mainly a header-only library


Probably because MSVC6 (I dont know 7) does not allow to write separate headers
and implementation for templates. This is why std templates (stl) is header only.
Did any of you except wryzy read the OP? He knows all about inline functions all about there use, and the fact that the compiler can ignore them ...

He was asking "Why do people do this?" ... which is "add the inline keyword while inside of a class declaration, which is inheirently inline anyway" ...

and the answer is ... we don't know. Because as far as any of us know, they ARE the exact same thing (and I have not found a case in my experience yet, where they are not).

But it's been years since I used the old MSVC 6 compiler (which had many quirks), or pre 3 GCC (the 2.9 series was odd on many subtle things) .. so it is probably one of the following reasons:

1. Some old compliers which treated them differently (this is a maybe, as I don't know of any case where this was definately true).

2. They didn't know any better, so they put it "just to be sure".

3. They wanted to document that it was inline, for humans who read the code - cause many a stupid human would probably try to "optimize" those functions by making them inline :).

4. They we're those stupid humans, and added the inline keyword to speed it up (thinking they we're smart).

I'm betting on 2-4.

This topic is closed to new replies.

Advertisement