Isn't "inline" becoming redundant?
The compiler is free to ignore the keyword "inline" (and sometimes must). Isn't it also true that the compiler might inline a function that was not declared as such?
If so, is "inline" in danger of deprecation?
Redundant? Certainly. Deprecated? I don't think inline is going to be deprecated any time soon. We used to have "auto" as a storage type for more than 30 years and compilers blissfully ignored it without deprecation. It was removed from C++09 only because it clashed with the newer auto which deduced types automatically from initializers. We have a similar experience with "register". Is there a single compiler that doesn't ignore register today? Is there a single C++ program that uses this keyword anyway?
inline is probably heading towards the same path: it will be ignored (it already is in some cases), but not deprecated. Deprecation occurs only when a feature is inherently flawed or harmful, not just because it's no longer used.
With respect to usefulness: I never use inline in my code. I trust my compiler's judgment (any compiler) for inlining the right functions. You're right: compilers are free to ignore inline when they realize that inlining a particular function is impossible or harmful. They are also free to inline a function even if it wasn't explicitly declared inline. The lesson drawn from this: don't bother declaring functions inline. Let the compiler do the right thing. Notice also that inlining a function isn't the compiler's exclusive prerogative. The linker is also free to do that, and so is even the operating system.
That said, programs using dynamic linking (dlls, shared libraries etc.) should abolish inline altogether as it leads to nasty incompatibility bugs.
Last edited by Danny; 05-29-2009 at 06:24 PM.
in my experience, the inline keyword is not redundant - it is very much required for several reasons.
A. a good function to inline is one
i. which has a stable (unlikely to change) implementation.
ii. which is frequently called (the program spends a signifanct portion of its time in calling and executing the function).
iii. which has a code size comparable to the code size required to set up the activation record and call the function.
the compiler or the linker is in no position to make a judgement about i.
unless an implementation has a good profile-guided optimizer, and the developer profiles the unoptimized program on a production machine in a production environment, and makes the profiling information available to such a compiler, it is in no position to make a judgement about ii.
B. determining correctly if it is beneficial to inline a function requires knowledge that the compiler or linker does not have at build-time.
a function that is worthwhile to inline when running on a processor with say a 4 MB processor cache and 4 GB memory (with no other serous load other than the program in question), may be harmful to inline if
i. You take it to a machine with a 2 MB processor cache and 2 GB of ram.
ii. The same 4 MB cache / 4 GB memory machine has several other programs also running simultaneously, and making demands on memory.
in production code, i need the inline key word; and i disallow automatic inlining by the compiler or linker. i can't afford to have them making ill-informed decisions about what are the functions that are good for inlining.
in general, the rule i follow is:
i. do not inline by default. consider inlining only if performance requirements mandate it.
ii. for order of magnitude improvements in performance, look at the data structures and algorithms first.
iii. profile the code in a real-life environment to identify candidate functions for inlining.
iv. choose the candidate set based on issues mentioned in A.
v. inline incrementally and profile the code at each stage.
there are no easy answers. see: http://www.parashift.com/c++-faq-lit...s.html#faq-9.3
Last edited by vijayan; 05-30-2009 at 02:11 PM.
I just want to add that inlining doesn't stop at the linker. The loader, the OS and if you're using some form of a managed environment (this isn't standard C++ of course but you can find it in the .Net framework for example) are also allowed to inline a function.
What worries me most is that the average C++ user rarely has any empirical evidence to support his or her judgment about inlining. They simply stick it wherever they feel like (or worse yet -- they use it everywhere). Since C++ is efficient enough in either case, most users can't tell the difference between an out of line version of the function and its inline version. So my advice is to use inline, if ever, only when you have tested and proved that 1) the compiler does respect the inline request and 2) the inlined function does improve performance. As a rule of thumb: if a function gets called only once or twice in the entire lifetime of the program, don't even bother. Finally, remember that inline can certainly cause damage: it could bloat the executable size, cause a dll h ell problem and even lead to subtle bugs (especially when during debugging).
Notice also that inline is implicitly present in your code. Every member function defined inside the class body is inline, as are all implicitly-defined special member functions (the ctor, dtor etc.).
Last edited by Danny; 05-30-2009 at 08:02 PM.
Both register and inline affect programs in visual studio, I think I may be 1 version old but its very likely this has not changed.
For some reason, many compilers are really picky about what can be auto-inline. The algorithm they use will quit and outline a function often if it is long (even if simple), has nested loops (even if simple), and a few other such things. Also, many compilers will let you control it 100% -- you can set flags to outline everything that does not have the keyword (it will do it, so long as keyword flagged functsions CAN be inlined -- no recursion etc.). It turns out that outlining functions that were auto-inlined can have nearly as much impact as inlining functions that the auto-inline refused to do. Most people just do not need to do this, I do not even fool with it as much as I used to as hardware has scaled faster than my demand for power on most fronts.
Register, this one is very risky. About 95% of the time it has made the program have either zero profile change(the usual) or degraded the profile. I have exactly 1 register keyword that I can remember that stays in my code base, and checking it has always shown it to improve run speed, so I have left it.
As Danny said (or implied), these keywords are best left out of most programs unless you A) need the performance and B) know how to profile your code to prove that version X and version Y have a significant performance change due to the use of the keyword and nothing else. For example, I know my current program has to get out of all functions and be back to the top of the loop in main fast enough to maintain at least 60 iterations of main per second most of the time. If the program is keeping pace, we leave it alone; if it falls behind (it self times this) it lets us know and we have to go profile and optimize it, a couple of times a year we end up looking for whatever cpu hog has slipped into the code, find it, and fix it. Its amazing how one or 2 careless lines of code can wreck such a system.
This must be a very old compiler (I mean, one that's older than Visual C++ 6) because the MSDN documentation suggests that register is completely ignored:
Originally Posted by jonnin
It does say that, but I have timed the code with and without the keyword and it makes a noticable difference, version is 2005. We were waiting for the one with the new c++ rules to upgrade again, and skipping vista entirely as we did with ME, so I guess we will upgrade next year to windows 7 version.
I'm curious. Did you disassemble the optimize code in both cases (with and without register) to see what the difference is?
No, but I can, I will try to do that this week.
Returning to the original question, there is a situation where the inline keyword is needed.
inline int triple(int a)
The linker issues an error when inline is removed from the header (tested with Visual Studio 2005).
I see no reason why this code should produce a linker error. triple() is an ordinary function. Declaring it inline just to appease the linker sounds odd.
Isn't this error caused by declaring the function as inline and non-inline in different places? This is an ODR violation. BTW, main should return int.
Try to remove the header file and instead, use a declaration of the function:
int triple(int a);
This should solve the problem I believe.
Well, you were right, register is ignored, the asm is the same. Very odd how it seemed to have an effect, but it could have been a debug mode test (I do not remember) where the alignment in the exe changed slightly or something. It also have actually been on visual 5.x or earlier, its a very old file.
Well, the point is whether the inline keyword is really ignored by the compilers. In this example it is not ignored (by this particular compiler). The linker will produce an error if the inline keyword is removed (because of the ODR).
Originally Posted by Danny
The triple() function is defined (and declared) in the header file and both translation units include the same header file. There cannot be an inline declaration and a non-inline declaration in different places (in the same build). Of course, if the inline keyword is removed, both translation units define the same function and the ODR is violated. That's the reason why the inline keyword is needed and it cannot be ignored by compilers (nor deprecated as hendrixj asked).
Originally Posted by Danny
Mmm... it compiles well. Maybe some Microsoft-only feature in VS2005?
Originally Posted by Danny
Yes, you are right. It is just an example to show a compiler that does not ignore the inline keyword.
Originally Posted by Danny
No one said inline was completely ignored by the compiler. If it were, I wouldn't bother telling programmers to avoid using it because it wouldn't matter anyway. *In some cases* inline is ignored, but the programmer can't always tell when that happens. This is the most problematic aspect of inline, I believe. Just by reading the source file you simply can't tell whether the function will be inlined or not, which leads to various portability, maintenance and testing problems.
The real question is: will the compiler inline triple() if you don't declare it inline explicitly?
Also, once you *define* a function in a header file, that function must be declared inline because otherwise you's have multiple definitions of the same function. This will cause a linker error unless of course the function is inline. That doesn't mean that inline is indispensable -- the right approach is to declare the function in a header file which will be #included in every translation unit, and *define* the function in a single .cpp file (without inline). This will eliminate the undefined symbol linker error.
As for main()'s return value: void main() is an pre-historic and deprecated habit that Microsoft compilers somehow still carry. You should get rid of it in favor of the standard compliant int main(). The fact that the compiler doesn't complain suggest mostly that the compiler needs to be updated (when it comes to Microsoft, this could take 20 years or so. We're still stuck with the horrendous BOOL typedef, aren't we?), not that the code is fine.
Last edited by Danny; 06-03-2009 at 10:54 PM.
By Ali Imran in forum Database
Last Post: 02-12-2002, 03:46 PM
By Doug Crowley in forum authorevents.patrick
Last Post: 09-08-2000, 05:27 PM
By pradeep in forum Enterprise
Last Post: 05-06-2000, 06:08 AM
Top DevX Stories
Easy Web Services with SQL Server 2005 HTTP Endpoints
JavaOne 2005: Java Platform Roadmap Focuses on Ease of Development, Sun Focuses on the "Free" in F.O.S.S.
Wed Yourself to UML with the Power of Associations
Microsoft to Add AJAX Capabilities to ASP.NET
IBM's Cloudscape Versus MySQL