I was reading the C++ FAQs and I noticed one sentence.
main() cannot be inline.
Why is this?
In C++ it is not legal to call the main function in your code, so there'd be no way it could ever be inlined.
Because the standard says so:
[2003: 3.6.1/3]:
The function main shall not be used (3.2) within a program. The
linkage (3.5) of main is implementation-defined. A program that
declares main to be inline or static is ill-formed. The name main is
not otherwise reserved. [Example: member functions, classes, and
enumerations can be called main, as can entities in other namespaces.
]
And why does it say so? Because it's trying to leave as much about the implementation of main to the individual .. well, implementation .. as is possible, and doesn't want to limit implementations by requiring that inline be valid here when it arguably has no practical benefit.
My friend on the committee confirmed this:
There's no reason why an inline main() wouldn't work, per se. [..] I could have a C++ interpreter that can invoke inlined main(). [..] [But] inline/static main() are forbidden in order to hopefully avoid confusion. I find it hard to imagine that the rationale would be anything additional to what's already been said in [this Q&A].
BTW, don't confuse the inline hint keyword with actually inlining functions. You can mark a function inline and it may not be physically inlined.
So, even if it were true that main "cannot be inlined" (and strictly speaking it is not true, though inlining main would be rather awkward and pointless as explained in other answers), it could theoretically still support the inline hint keyword just fine.
It doesn't for the reason stated above, and in litb's answer: it would complicate matters for no real benefit.
The C runtime library needs to find this symbol in order to "know" which function to run.
You cannot directly call main() (it's forbidden in c++), so there is no point of inlining it.
Usually main() is called from systems init() function. Thus, it is needed that there can be exactly one definition for main().
Now, if we can inline the main() function and include in a header file then, for every translation unit there will be different definition for main(). Which is not allowed. You can declare main() in a namespace and inline it. But not the global main().
firstly you must understand how work function with inline
example:
inline void f() {
int a = 3;
a += 3;
cout << a;
}
int main() {
f();
return 0;
}
will look like to the compiler as:
int main() {
int a = 3;
a += 3;
cout << a;
return 0;
}
looking at this example, how do you want to make main inline? This method is inline immediately.
The C++ standard says that the main function cannot be inlined, per #Tomalak Geret'kal's reply. This response discusses possibility of inlining of the main function, were the restriction in the Standard removed.
Definition of Inline
The inline keyword is a suggestion to the compiler to paste the contents of the function in-situ. One intent is to remove the overhead present in calling and returning from a function (subroutine).
An important situation of inlining is the case where there is a pointer to the function. In this case, there must be at least one static copy of the function. In this case, the linker can resolve "external linkages" of the inlined function because there is one static version.
Important to note that the compiler and linker determine whether or not to paste the contents or calls a single instance of the function.
Also of note, functions that are not tagged by the programmer may also be inlined by the compiler.
Inlining the main function
Since there is only one invocation of main allowed, how it is linked is up to the compiler. Single instances of inline functions are allowed by the Standard. The compiler is allowed to convert an inlined function into a function call to a single instance. So the compiler would ignore an inline suggestion for the main function.
The compiler and linker would have to insure that only one instance of the inlined main function exists. This where the tricky part comes in, especially with external linkage. One process for ensuring one instance is to leave information that a translation has a 'main' function whether or not it is inlined. Note: When a call to an inline function is made, the compiler is allowed to remove the function from the symbol tables for external linkage, since the idea is that the function won't be called by external functions.
Summary
Technically, there is nothing preventing the main function from being inlined. The machinery already exists for converting inlined functions into single instances and for identifying multiple instances of a function. When there is a pointer to an inlined function, a single instance of a function is made, so it has an address. This machinery would satisfy the Run-Time Library requirements for main having an address. In the case of inline for the main function, it would be ignored but there should not be any reason to prevent this syntax (except confusing people). After all, there are already syntax cases that are redundant, such as declaring a parameter that is passed by value (copy) as const.
"That's just my opinion, I could be wrong." -- Dennis Miller, comedian.
Others have remarked that an invocation of main can not meaningfully be inlined at the machine code level. That's rubbish. It would require a bit of help from the linker (like global optimization) or else per-application recompilation of a bit of the runtime library, but it's quite doable, no technical problem here.
However, the hinting effect of inline, that calls should preferably be inlined, is irrelevant for a function that is only called once and at the top level of control, as main is.
The only guaranteed effect of inline is to allow an external linkage function to be defined (identically) in two or more translation units, i.e. affecting the One Definition Rule.
As a practical matter this allows the definition to be placed in a header file, and placing it in a header file is a also practically necessary to guarantee identical definitions.
That does not make sense for main, so there is no reason for main to be inline.
You can only define main once. So putting inline would not serve any purpose - inline only has a significant purpose on functions you can define multiple times in a program (all definitions will be treated as if there were only one definition and all definitions are required to be the same).
Because inline functions can be defined multiple times in a program, and inline also serves the purpose of making calls to an inline-marked function as fast as possible, the Standard requires inline functions to be defined in every translation unit in which it is used. So compilers will usually throw away the definition of a function if it is inline and the function wasn't used by the code in the current translation unit. To do that for main would be entirely wrong, which goes to show that inline and the semantics main has is entirely incompatible.
Note that the question in your title "Why main() in C++ cannot be inlined?" and the statement you quote out of the Standard concern different things. You are asking whether the function can be inlined, which commonly is understood to insert the code of a called function completely or partially into the calling function. Just marking a function inline doesn't imply inlining that function at all. It's entirely the compiler's decision, and of course if you never call main (and you cannot do so) then there is nothing to be inlined.
If you linked statically to the CRT and enabled some link-time compilation-inlining (like MSVC has) it might be possible to inline it.
But it doesn't really make sense. It will be called once and that function call-overhead is practically naught compared to everything else that is done before the first line in main executes.
...
Aaand, it is an easy way to force the symbol to appear only once in your executable. :)
There are a number of basic reasons. Basically, main is called from
the basic initialization routine of the runtime, and only from there.
That code was (obviously) compiled without knowing that your main was
inlined. Modern compiler technology is capable of inlining across
module boundaries, but it's an advanced feature, not supported by many
older compilers. And of course, the benefits of inlining are only
present when a function is called very frequently; by definition, main
will be called exactly once, no more, no less.
I see the standard says so, but the real practical answer would be as simple as stating that the runtime added to every C and C++ program has to call to some point in the executable. That function should have an external symbol (and address when running) so that the linker can find it to be called at the beginning of execution. Hence you cannot declare it as inline, because inlined the compiler wouldn't generate an external symbol for it.
Since its the main() function, which starts the execution, when the code gets compiled to binary, everything is in the main() itself. so you can say, it already inlined!
And yes, its illegal to use inline for your C++ program, that's more about a syntax!
For most combinations of compiler/archetecture, the main() function in the source becomes a reasonably normal function in the final binary. This is only because it's convenient on those archetectures, not because the standard says it must be so.
On memory constrained archetectures, many compilers, ones which produce a flat binary (like intex hex format) instead of a dynamic linker friendly container (like elf or xcoff), optimize all of the boilerplate away, since it would just be bloat. Some architectures don't support function calls at all (only a limited subset of C++ is possible on these platforms.)
In order to support the widest variety of such architectures and build environments, the standard elects keep the semantics of main() as open as possible, so that the compiler can do what's right for the widest variety of platforms. That means that many features available in the language as a whole cannot apply to the startup and shutdown of the application itself.
If you need something like an inline main() (or reentrancy, or any fancy feature) you can of course call the main function something else:
inline int myMain(int argc, char **argv) { /* whatever */ }
int main(int argc, char **argv) { return myMain(argc, argv); }
Inline functions are having static scope by-default. It means if we declare main() as inline, it's scope will be limited to the file where it is defined. Yet, the C start-up library (provided by compiler vendor) needs 'main' to be a global symbol. There are some compilers that allow to modify entry point function (e.g. main) using linker flags.
inline functions don't usually have an address, so there is no portable way to call main, main() needs an address on which the init code can jump into. Inlined functions are meant to be stuck into the calling function, if main is inlined, it should be inlined into the init code of the program, which is not portable either.
operating system loads binary data to memory; looks for entry point (the 'main' symbol in c/c++); makes far jump to the addres of the entry point label. Operating system does not know anything about main function in your code until the program is not loaded.
Related
See title: what does it mean for a C++ function to be inline?
It means one thing and one thing only: that the compiler will elide multiple definitions of the function.
A function normally cannot be defined multiple times (i.e. if you place a non-inline function definition into a header and then #include it into multiple compilation units you will receive a linker error). Marking the function definition as "inline" suppresses this error (the linker ensures that the Right Thing happens).
IT DOES NOT MEAN ANYTHING MORE!
Most significantly, it does NOT mean that the compiler will embed the compiled function into each call site. Whether that occurs is entirely up to the whims of the compiler, and typically the inline modifier does little or nothing to change the compiler's mind. The compiler can--and does--inline functions that aren't marked inline, and it can make function calls to functions that are marked inline.
Eliding multiple definitions is the thing to remember.
The function is placed in the code, rather than being called, similar to using macros (conceptually).
This can improve speed (no function call), but causes code bloat (if the function is used 100 times, you now have 100 copies).
You should note this does not force the compiler to make the function inline, and it will ignore you if it thinks its a bad idea. Similarly the compiler may decide to make normal functions inline for you.
This also allows you to place the entire function in a header file, rather than implementing it in a cpp file (which you can't anyways, since then you get an unresolved external if it was declared inline, unless of course only that cpp file used it).
As well as the other (perfectly correct) answers about the performance implications of inline, in C++ you should also note this allows you to safely put a function in a header:
// my_thing.h
inline int do_my_thing(int a, int b) { return a + b; }
// use_my_thing.cpp
#include "my_thing.h"
...
set_do_thing(&do_my_thing);
// use_my_thing_again.cpp
...
set_other_do_thing(&do_my_thing);
This is because the compiler only includes the actual body of the function in the first object file that needs a regular callable function to be compiled (normally because it's address was taken, as I showed above).
Without the inline keyword, most compilers would give an error about multiple definition, eg for MSVC:
use_my_thing_again.obj : error LNK2005: "int __cdecl do_my_thing(int,int)" (?do_my_thing##YAHHH#Z) already defined in use_my_thing.obj
<...>\Scratch.exe : fatal error LNK1169: one or more multiply defined symbols found
#OldMan
The compilers only inline non marked as inline functions ONLY if you request it to do so.
Only if by "request" you mean "turn on optimizations".
Its correct only on the effcts nto the casuse.
It's correct in both.
Inline do not generate any extra info that the linker may use. Compiel 2 object files and check. It allow multiple definitions exaclty because the symbols are not exported! Not because that is its goal!
What do you mean, "the symbols are not exported"? inline functions are not static. Their names are visible; they have external linkage. To quote from the C++ Standard:
void h();
inline void h(); // external linkage
inline void l();
void l(); // external linkage
The multiple definitions thing is very much the goal. It's mandatory:
An inline function shall be defined in every translation unit in which it is used and shall have exactly the
same definition in every case (3.2). [Note: a call to the inline function may be encountered before its definition
appears in the translation unit. ] If a function with external linkage is declared inline in one translation
unit, it shall be declared inline in all translation units in which it appears; no diagnostic is required. An
inline function with external linkage shall have the same address in all translation units.
The function body is literally inserted inside the caller function. Thus, if you have multiple calls to this function, you get multiple copies of the code. The benefit is you get faster execution.
Usually very short function are inlined, when the copy of the function body would be not much bigger than the usual prologue/epilogue code generated for the normal function call.
You can read more at MSDN article about inline - http://msdn.microsoft.com/en-us/library/z8y1yy88.aspx
Inline functions alter the performance profile of your application by possibly generating instructions that are placed in the code segment of your application. Whether a function is inlined is at the discretion of your compiler. In my experience, most modern compilers are good at determining when to comply with a user's request to inline.
In many cases, inlining a function will improve its performance. There is an inherent overhead to function calls. There are reasons, however, why inlining a function could be negative:
Increasing the size of the binary executable by duplicating code could lead to disk thrashing, slowing your application down.
Inlining code could contribute to cache misses, or possibly contribute to cache hits depending on your architecture.
The C++ FAQ does a good job of explaining the intricacies of the keyword:
http://www.parashift.com/c++-faq-lite/inline-functions.html#faq-9.3
Informally, it means that compilers are allowed to graft the contents of the function onto the call site, so that there is no function call. If your function has big control statements (e.g., if, switch, etc.), and the conditions can be evaluated at compile time at the call site (e.g., constant values used at call site), then your code ends up much smaller (the unused branches are dropped off).
More formally, inline functions have different linkage too. I'll let C++ experts talk about that aspect.
Calling a function imposes a certain performance penalty for the CPU over just having a linear stream of instructions. The CPU's registers have to be written to another location, etc. Obviously the benefits of having functions usually outweigh the performance penalty. But, where performance will be an issue, for example the fabled 'inner loop' function or some other bottleneck, the compiler can insert the machine code for the function into the main stream of execution instead of going through the CPU's tax for calling a function.
A function that you flag as inline is allowed to be inlined by the compiler. There is no guarantee that compielr will do it. The compiler itself uses complex semantics to device when to do it or not.
When the compiler decides that a function should be inlined, the call to the function, in the caller code is replaced by the code of the calee. This means you save up stack operations, the call itself and improve locality of code cache. Sometimes that may lead to huge performance gains. Specially in 1 line data access functions, like the accessors used in Object Oriented code.
The cost is that usually that will result in larger code, what might hurt performance. This is why setting a function to inline is only a "green flag" to the compiler, that it does not need to follow. The compiler will try to do what is best.
As a rule of thumb for beginners that don't want to deal with linkage peculiarities. inline function are to be called by other function in same compilation units. If you want to implement an inline function that can be used on multiple compilation units, make it an header file declared and implemented inline function.
Why?
Example: at header file inlinetest.h
int foo();
inline int bar();
At the compilation unit inlinetest.cpp
int foo(){ int r = bar(); return r; }
inline int bar(){ return 5;};
Then at the main.cpp
#include "inlinetest.h"
int main()
{
foo();
//bar();
}
Compile one object file at a time. If you uncomment that "bar" call you will have an error. Because the inline function is only implemented on the inlinetest.o object file and is not exported. At same time the foo function, very likely has embedded on it the code of the bar function (since bar is single line no I/O operation then its very likely to be inlined)
But if at the header file you had declared the inline function and implemented it inline then you would be able to use it at any compilation unit that includes that header.
("code sample");
Remove the inline keyword and compiler will NOT cause the error even with bar call at main And no inline will happen unless you ask the compiler to inline all functions. That is not standard behavior on most compilers.
!! Specific on frequently used methods like getter & setter. !!
I have no idea when the keyword inline should be used. Ofc I know what it does, but I still have no idea.
According to an interview with Bjarne Stroustrup he said:
My own rule of thumb is to use inlining (explicitly or implicitly) only for simple one- or two-line functions that I know to be frequently used and unlikely to change much over the years. Things like the size() function for a vector. The best uses of inlining is for function where the body is less code than the function call and return mechanism, so that the inlined function is not only faster than a non-inlined version, but also more compact in the object core: smaller and faster.
But I often read that the compiler automatically inline short functions like getter, setter methods (in this case getting the size() of a vector).
Can anyone help?
Edit:
Coming back to this after years and more experience the high performance C+++ programming, inline can indeed help. Working in the games industry even forceinline sometimes makes a difference, since not all compilers work the same. Some might inline automatically some don't.
My advice is if you work on frameworks, libraries or any heavily used code consider the use of inline, but this is just general advice anyway since you want such code to be fully optimized for any compiler. Always using inline might not be the best, because you'll also need the class definition for this part of the code. Sometimes this can increase compilation times if you can't use forward declarations anymore.
another hint: you can use C++14 auto return type deduction even with seperating the function definition:
MyClass.h
class MyClass
{
int myint;
public:
auto GetInt() const;
}
inline auto MyClass::GetInt() const { return myint; }
all in one .h file.
Actually, inline keyword is not for the compiler anymore, but for the linker.
That is, while inline in function declaration still serves for most compilers as a hint, on high optimization setting they will inline things without inline and won't inline things with inline, if they deem it better for the resulting code.
Where it is still necessary is to mark function symbols as weak and thus circumvent One Definition Rule, which says that in given set of object files you want to make into a binary, each symbol (such as function) shall be present only once.
Bjarne's quote is old. Modern compilers are pretty smart at it.
That said, if you don't use Link Time Code Generation, the compiler must see the code to inline it. For functions used in multiple .cpp files, that means you need to define them in a header. And to circumvent the One Definition Rule in that case, you must define those functions as inline.
Class members defined inside the class are inline by default, though.
The below speaks specifically to C++:
The inline keyword has nothing to do with inlining.
The inline keyword allows the same function to be defined multiple times in the same program:
Every program shall contain exactly one definition of every non-inline function or variable that is odr-used in that program; no diagnostic required.
§3.2 [basic.def.odr]
Attaching meaning beyond this to the inline keyword is erroneous. The compiler is free to inline (or not) anything according to the "as-if rule":
A conforming implementation executing a well-formed program shall produce the same observable behavior as one of the possible executions of the corresponding instance of the abstract machine with the same program and the same input.
§1.9 [intro.execution]
Considering what compiler optimizations can do, the only use of inline I have today is for non-template function whose body is defined inside headers files outside class bodies.
Everything is defined (note: defined != declared) inside class bodies is inline by default, just as templates are.
The meaning of inline in fact is: "Defined in header, potentially imported in multiple sources, just keep just one copy of it" told to the linker.
May be in c++35 someone will finally decide to replace that keyword with another one more meaningful.
C++ standard Section 7.1.2 Point 2:
(...) The inline specifier indicates to the implementation that
inline substitution of the function body at the point of call is to be
preferred to the usual function call mechanism. An implementation
is not required to perform this inline substitution at the point of
call (...)
In other words instead of havin a single code for your function, that is called several times, the compiler may just duplicate your code in the various places the function is called. This avoids the little overhead related to the function call, at the cost of bigger executables.
Be aware that inline keyword may be used also with namespaces, but with a very different meaning. Members of an inline namespace can be used in most respects as though they were members of the enclosing namespace. (see Standard, section 7.3.1 point 8).
Edit:
The google style guide recommends to inline only when a function is ten lines or less.
I'm answering the question my self!: Solution: After a few performance tests, the rule of thumb from Stroustrup is right! inlining Short functions like the .size() from vector can improve the performance (.size() calls are used frequently). But the impact is only noticeable for FREQUENTLY used functions. If a getter/setter method is used a lot, inlining it might increase the performance.
Stroustrup:
Don’t make statements about “efficiency” of code without first doing
time measurements. Guesses about performance are most unreliable.
I have the following class defined in a foo.h header file
class Foo {
public:
inline int Method();
};
inline int Foo::Method() { // Implementation }
I would like now to move the implementation to a foo.cpp file. To this end, I have to remove the inline keyword and move the implementation of the method to a foo.cpp file like this
#include `foo.h`
inline int Foo::Method() { // Implementation }
I have two questions:
Is my statement about the removal of the inline keyword correct? Should it be necessarily removed?
How typically the removal of the inline keyword affect the performance (practically all my methods are inlined)?
Thank you very much in advance.
If you moved the function definition from a header to a cpp file, you MUST remove the inline keyword all all locations for that function. With older linkers it might make things slightly slower, but with modern linkers you should notice no real difference in performance.*
There are certain cases where a public member function can be inline, but that's just a bad idea. Don't do it. Arguments can be made for marking certain private member functions as inline, but in reality what you really want in those to be __attribute__((always_inline)) or __forceinline
*In extremely rare cases it will make a difference, but 99% of the time it won't, and 99.9% of what's left you don't care. If measurements show you hit that one-in-ten-thousand, you can use the aformentioned __forceinline.
Keyword inline is redundant in the class. It is implied if you have a function body.
In the implementation file it is also fairly redundant.
The only use of it is if you define a free function in a header (or a member function outside the class, but in the header) to avoid multiple bodies.
Optimization-wise on mist modern compilers it's even more redundant, they inline anything in sight without question anyway, or ignore your keyword at will.
The inline usage must be consistent! From 7.1.2p4:
An inline function shall be defined in every translation unit in which it is odr-used and shall have exactly the same definition in every case (3.2). [ Note: A call to the inline function may be encountered before its definition appears in the translation unit. —end note ] If the definition of a function appears in a translation unit before its first declaration as inline, the program is ill-formed. If a function with external linkage is
declared inline in one translation unit, it shall be declared inline in all translation units in which it appears; no diagnostic is required. ...
You, and the people here giving advice about small functions, are looking at inline the old-fashioned way.
inline used to mean "I want this code to run quickly, so whenever I call this function, I want you to expand it in-place to avoid the overhead of a function call."
That's a really good optimization. It's so good, in fact, that the compiler will eagerly do it even if you don't specify inline.
The compiler is also free to not expand your inline functions. So you really don't have to worry about how it will affect performance, because the compiler can and will ignore inline if you use it in a stupid way.
In fact, compilers today almost always ignore your use of inline, and just do whatever they think is best.
So, knowing that, why do people still use inline?
There's only one reason to use inline nowadays, and that's to work around the One Definition Rule (ODR).
In C/C++, you're only allowed to define a function once. If you do this:
int foo() { /* do something */ }
int foo() { /* do something else */ }
the compiler will complain that you've defined the same function twice.
That looks like a silly example, but it's particularly easy to do something like that when you're using #include - if you defined your function in a header, and you #include the same header twice, this is exactly what you're doing.
Thankfully, inline has another use which is still valid today: if you mark a function as inline, it forces the compiler to silence ODR issues, making it possible to define your function in a header.
In other words, inline now means "I want to define this function in a header."
When you look at it that way, it should be clear that you should remove the inline when moving the function into a cpp file.
For interest sake, there's a couple places where functions are implicitly made inline. One of them is in class member functions:
struct Foo {
void bar() { /* do something */ }
};
I've seen people mark functions like this inline, but that's completely redundant. The compiler does it anyway; there's no need to worry about ODR, and there's no performance to be gained.
The other place is in templates. Since templates have to be defined in headers, they're exempt from the ODR, and inlineing them is redundant.
If the function isn't TINY (or takes several arguments, but doesn't do much, such as a constructor or similar, that takes a bunch of things, and just copies it to somewhere inside the class), inlining it will have little impact on performance in the first place. Setters and getters are usually good candidates to inline, since they (typically) just copy data from one place to another, and can easily be done where the call takes place.
As others have said, it's a "please compiler, if I may ask you kindly, consider inlining this function" - it's not a "make this function inline". The compiler, on the other hand, will often inline functions REGARDLESS of whether there is an inline keyword. It looks at the size of the function, the number of calls and how much larger the code gets from inlining.
If you move the function to "foo.cpp", it will ONLY get inline inside the "foo.cpp" compile unit (typically, compile unit = source file).
That is unless you have a compiler capable of "whole program optimization" or similar tricks, and enable that feature - this basically means that instead of producing a ready to link object file with machine code, the compiler produces a "parsed, but not completely translated to machine instructions" object file. Then, when it comes to finally putting the executable (or shared library) toegether, the compiler/linker will produce one large lump of machine code from the "halfway" code. Both MS and GCC do support this, but I don't know how well it works for large projects.
Edit:
As per Mooing Duck's comment: An inline function doesn't make a real function name in the object file, so the linker may also give errors for unresolved symbol int Foo::Method() [or some wording to that extent].
End edit.
If performance is critical, you should measure the current code's performance, then make your changes, and measure it again. If it's significantly different, you'll have your answer. If it's faster (because of less inlining leading to more cache-hit rate for other bits of code, for example), then that's good. If it's slower, you'll have to put back (some of) the functions into the header file. Or live with it being slower... Or find some other way of making it faster again... The choices are yours (and, if you work in a group, some other people may have a say in the final decision, of course). It's almost impossible for anyone to say for SURE which way it will go without at the very least understanding the whole programs architecture and what goes on in the class - which, given the name "foo.cpp" in the post is probably not the REAL code...
It may be confusing, but you should not think of the purpose of inline to make the compiler inline a function. (Modern compilers are way smarter than you in regards to when a function should be inlined or not anyway).
No, the real purpose of inline is to tell the linker to not worry about multiple definitions of the function. If you put the definition of a (non-member) function in a header, you should mark it inline to avoid linker errors.
2. How typically the removal of the inline keyword affect the performance (practically all my methods are inlined)?
The inline keyword tells the compiler to take the implementation code of that function and put it in place of the function call. This reduces the number of function calls on the stack and if used correctly, can improve the performance of your program.
The inline keyword should only be used with small functions. Get and Set functions are good examples. They set the value of one variable or return the value of one variable.
If you make a function with a lot of code inline, it can increase the size of your code by a lot (depending on the size of the function code and how many times that function is used) and actually DECREASE the performance of your program.
I had a discussion with Johannes Schaub regarding the keyword inline.
The code there was this:
namespace ... {
static void someFunction() {
MYCLASS::GetInstance()->someFunction();
}
};
He stated that:
Putting this as an inline function may
save code size in the executable
But according to my findings here and here it wouldn't be needed, since:
[Inline] only occurs if the compiler's cost/benefit analysis show it to be profitable
Mainstream C++ compilers like Microsoft Visual C++ and GCC support an option that lets the compilers automatically inline any suitable function, even those not marked as inline functions.
Johannes however states that there are other benefits of explicitly specifying it. Unfortunately I do not understand them. For instance, he stated that And "inline" allows you to define the function multiple times in the program., which I am having a hard time understanding (and finding references to).
So
Is inline just a recommendation for the compiler?
Should it be explicitly stated when you have a small function (I guess 1-4 instructions?)
What other benefits are there with writing inline?
is it needed to state inline in order to reduce the executable file size, even though the compiler (according to wikipedia [I know, bad reference]) should find such functions itself?
Is there anything else I am missing?
To restate what I said in those little comment boxes. In particular, I was never talking about inlin-ing:
// foo.h:
static void f() {
// code that can't be inlined
}
// TU1 calls f
// TU2 calls f
Now, both TU1 and TU2 have their own copy of f - the code of f is in the executable two times.
// foo.h:
inline void f() {
// code that can't be inlined
}
// TU1 calls f
// TU2 calls f
Both TUs will emit specially marked versions of f that are effectively merged by the linker by discarding all but one of them. The code of f only exists one time in the executable.
Thus we have saved space in the executable.
Is inline just a recommendation for the compiler?
Yes.
7.1.2 Function specifiers
2 A function declaration (8.3.5, 9.3, 11.4) with an inline specifier declares an inline function. The inline
specifier indicates to the implementation that inline substitution of the function body at the point of call
is to be preferred to the usual function call mechanism. An implementation is not required to perform this
inline substitution at the point of call; however, even if this inline substitution is omitted, the other rules
for inline functions defined by 7.1.2 shall still be respected.
For example from MSDN:
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.
Note though:
3.2 One definition rule
3 [...]An inline function shall be defined in every translation unit in which it is used.
4 An inline function shall be defined in every translation unit in which it is used and shall have exactly
the same definition in every case (3.2). [ Note: a call to the inline function may be encountered before its
definition appears in the translation unit. —end note ] If the definition of a function appears in a translation
unit before its first declaration as inline, the program is ill-formed. If a function with external linkage is
declared inline in one translation unit, it shall be declared inline in all translation units in which it appears;
no diagnostic is required. An inline function with external linkage shall have the same address in all
translation units. A static local variable in an extern inline function always refers to the same object.
A string literal in the body of an extern inline function is the same object in different translation units.
[ Note: A string literal appearing in a default argument expression is not in the body of an inline function
merely because the expression is used in a function call from that inline function. —end note ] A type
defined within the body of an extern inline function is the same type in every translation unit.
[Note: Emphasis mine]
A TU is basically a set of headers plus an implementation file (.cpp) which leads to an object file.
Should it be explicitly stated when you have a small function (I
guess 1-4 instructions?)
Absolutely. Why not help the compiler help you generate less code? Usually, if the prolog/epilog part incurs more cost than having it inline force the compiler to generate them? But you must, absolutely must go through this GOTW article before getting started with inlining: GotW #33: Inline
What other benefits are there with writing inline?
namespaces can be inline too. Note that member functions defined in the class body itself are inline by default. So are implicitly generated special member functions.
Function templates cannot be defined in an implementation file (see FAQ 35.12) unless of course you provide a explicit instantiations (for all types for which the template is used -- generally a PITA IMO). See the DDJ article on Moving Templates Out of Header Files (If you are feeling weird read on this other article on the export keyword which was dropped from the standard.)
Is it needed to state inline in order to reduce the executable file
size, even though the compiler
(according to wikipedia [I know, bad
reference]) should find such functions
itself?
Again, as I said, as a good programmer, you should, when you can, help the compiler. But here's what the C++ FAQ has to offer about inline. So be wary. Not all compilers do this sort of analysis so you should read the documentation on their optimization switches. E.g: GCC does something similar:
You can also direct GCC to try to integrate all “simple enough” functions into their callers with the option -finline-functions.
Most compilers allow you to override the compiler's cost/benefit ratio analysis to some extent. The MSDN and GCC documentation is worth reading.
Is inline just a recommendation for the compiler?
Yes. But the linker needs it if there are multiple definitions of the function (see below)
Should it be explicitly stated when you have a small function (I guess 1-4 instructions?)
On functions that are defined in header files it is (usually) needed. It does not hurt to add it to small functions (but I don't bother). Note class members defined within the class declaration are automatically declared inline.
What other benefits are there with writing inline?
It will stop linker errors if used correctly.
is it needed to state inline in order to reduce the executable file size, even though the compiler (according to wikipedia [I know, bad reference]) should find such functions itself?
No. The compiler makes a cost/benefit comparison of inlining each function call and makes an appropriate choice. Thus calls to a function may be inlined in curtain situations and not inlined in other (depending on how the compilers algorithm works).
Speed/Space are two competing forces and it depends what the compiler is optimizing for which will determine weather functions are inlined and weather the executable will grow or shrink.
Also note if excessively aggressive inlining is used causing the program to expand too much, then locality of reference is lost and this can actually slow the program down (as more executable pages need to be brought into memory).
Multiple definition:
File: head.h
// Without inline the linker will choke.
/*inline*/ int add(int x, int y) { return x + y; }
extern void test()
File: main.cpp
#include "head.h"
#include <iostream>
int main()
{
std::cout << add(2,3) << std::endl;
test();
}
File: test.cpp
#include "head.h"
#include <iostream>
void test()
{
std::cout << add(2,3) << std::endl;
}
Here we have two definitions of add(). One in main.o and one in test.o
Yes. It's nothing more.
No.
You hint the compiler that it's a function that gets called a lot, where the jump-to-the-function part takes a lot of the execution time.
The compiler might decide to put the function code right where it gets called instead where normal functions are. However, if a function is inlined in x places, you need x times the space of a normal function.
Always trust your compiler to be much smarter than yourself on the subject of premature micro-optimization.
Actually, inline function may increase executable size, because inline function code is duplicated in every place where this function is called. With modern C++ compilers, inline mostly allows to programmer to believe, that he writes high-performance code. Compiler decides itself whether to make function inline or not. So, writing inline just allows us to feel better...
With regards to this:
And "inline" allows you to define the function multiple times in the program.
I can think of one instance where this is useful: Making copy protection code harder to crack. If you have a program that takes user information and verifies it against a registration key, inlining the function that does the verification will make it harder for a cracker to find all duplicates of that function.
As to other points:
inline is just a recommendation to compiler, but there are #pragma directives that can force inlining of any function.
Since it's just a recommendation, it's probably safe to explicitly ask for it and let the compiler override your recommendation. But it's probably better to omit it altogether and let the compiler decide.
The obfuscation mentioned above is one possible benefit of inlining.
As others have mentioned, inline would actually increase the size of the compiled code.
Yes, it will readily ignore it when it thinks the function is too large or uses incompatible features (exception handling perhaps). Furthermore, there is usually a compiler setting to let it automatically inline functions that it deems worthy (/Ob2 in MSVC).
It should be explicitly stated if you put the definition of the function in the header file. Which is usually necessary to ensure that multiple translation units can take advantage of it. And to avoid multiple definition errors. Furthermore, inline functions are put in the COMDAT section. Which tells the linker that it can pick just one of the multiple definitions. Equivalent to __declspec(selectany) in MSVC.
Inlined functions don't usually make the executable smaller. Since the call opcode is typically smaller than the inlined machined code, except for very small property accessor style functions. It depends but bigger is not an uncommon outcome.
Another benefit of in-lining (note that actual inlining is sometimes orthogonal to use of the "inline" directive) occurs when a function uses reference parameters. Passing two variables to a non-inline function to add its first operand to the second would require pushing the value of the first operand and the address of the second and then calling a function which would have to pop the first operand and address of the second, and then add the former value indirectly to the popped address. If the function were expanded inline, the compiler could simply add one variable to the other directly.
Actually inlining leads to bigger executables, not smaller ones.
It's to reduce one level of indirection, by pasting the function code.
http://www.parashift.com/c++-faq-lite/inline-functions.html
See title: what does it mean for a C++ function to be inline?
It means one thing and one thing only: that the compiler will elide multiple definitions of the function.
A function normally cannot be defined multiple times (i.e. if you place a non-inline function definition into a header and then #include it into multiple compilation units you will receive a linker error). Marking the function definition as "inline" suppresses this error (the linker ensures that the Right Thing happens).
IT DOES NOT MEAN ANYTHING MORE!
Most significantly, it does NOT mean that the compiler will embed the compiled function into each call site. Whether that occurs is entirely up to the whims of the compiler, and typically the inline modifier does little or nothing to change the compiler's mind. The compiler can--and does--inline functions that aren't marked inline, and it can make function calls to functions that are marked inline.
Eliding multiple definitions is the thing to remember.
The function is placed in the code, rather than being called, similar to using macros (conceptually).
This can improve speed (no function call), but causes code bloat (if the function is used 100 times, you now have 100 copies).
You should note this does not force the compiler to make the function inline, and it will ignore you if it thinks its a bad idea. Similarly the compiler may decide to make normal functions inline for you.
This also allows you to place the entire function in a header file, rather than implementing it in a cpp file (which you can't anyways, since then you get an unresolved external if it was declared inline, unless of course only that cpp file used it).
As well as the other (perfectly correct) answers about the performance implications of inline, in C++ you should also note this allows you to safely put a function in a header:
// my_thing.h
inline int do_my_thing(int a, int b) { return a + b; }
// use_my_thing.cpp
#include "my_thing.h"
...
set_do_thing(&do_my_thing);
// use_my_thing_again.cpp
...
set_other_do_thing(&do_my_thing);
This is because the compiler only includes the actual body of the function in the first object file that needs a regular callable function to be compiled (normally because it's address was taken, as I showed above).
Without the inline keyword, most compilers would give an error about multiple definition, eg for MSVC:
use_my_thing_again.obj : error LNK2005: "int __cdecl do_my_thing(int,int)" (?do_my_thing##YAHHH#Z) already defined in use_my_thing.obj
<...>\Scratch.exe : fatal error LNK1169: one or more multiply defined symbols found
#OldMan
The compilers only inline non marked as inline functions ONLY if you request it to do so.
Only if by "request" you mean "turn on optimizations".
Its correct only on the effcts nto the casuse.
It's correct in both.
Inline do not generate any extra info that the linker may use. Compiel 2 object files and check. It allow multiple definitions exaclty because the symbols are not exported! Not because that is its goal!
What do you mean, "the symbols are not exported"? inline functions are not static. Their names are visible; they have external linkage. To quote from the C++ Standard:
void h();
inline void h(); // external linkage
inline void l();
void l(); // external linkage
The multiple definitions thing is very much the goal. It's mandatory:
An inline function shall be defined in every translation unit in which it is used and shall have exactly the
same definition in every case (3.2). [Note: a call to the inline function may be encountered before its definition
appears in the translation unit. ] If a function with external linkage is declared inline in one translation
unit, it shall be declared inline in all translation units in which it appears; no diagnostic is required. An
inline function with external linkage shall have the same address in all translation units.
The function body is literally inserted inside the caller function. Thus, if you have multiple calls to this function, you get multiple copies of the code. The benefit is you get faster execution.
Usually very short function are inlined, when the copy of the function body would be not much bigger than the usual prologue/epilogue code generated for the normal function call.
You can read more at MSDN article about inline - http://msdn.microsoft.com/en-us/library/z8y1yy88.aspx
Inline functions alter the performance profile of your application by possibly generating instructions that are placed in the code segment of your application. Whether a function is inlined is at the discretion of your compiler. In my experience, most modern compilers are good at determining when to comply with a user's request to inline.
In many cases, inlining a function will improve its performance. There is an inherent overhead to function calls. There are reasons, however, why inlining a function could be negative:
Increasing the size of the binary executable by duplicating code could lead to disk thrashing, slowing your application down.
Inlining code could contribute to cache misses, or possibly contribute to cache hits depending on your architecture.
The C++ FAQ does a good job of explaining the intricacies of the keyword:
http://www.parashift.com/c++-faq-lite/inline-functions.html#faq-9.3
Informally, it means that compilers are allowed to graft the contents of the function onto the call site, so that there is no function call. If your function has big control statements (e.g., if, switch, etc.), and the conditions can be evaluated at compile time at the call site (e.g., constant values used at call site), then your code ends up much smaller (the unused branches are dropped off).
More formally, inline functions have different linkage too. I'll let C++ experts talk about that aspect.
Calling a function imposes a certain performance penalty for the CPU over just having a linear stream of instructions. The CPU's registers have to be written to another location, etc. Obviously the benefits of having functions usually outweigh the performance penalty. But, where performance will be an issue, for example the fabled 'inner loop' function or some other bottleneck, the compiler can insert the machine code for the function into the main stream of execution instead of going through the CPU's tax for calling a function.
A function that you flag as inline is allowed to be inlined by the compiler. There is no guarantee that compielr will do it. The compiler itself uses complex semantics to device when to do it or not.
When the compiler decides that a function should be inlined, the call to the function, in the caller code is replaced by the code of the calee. This means you save up stack operations, the call itself and improve locality of code cache. Sometimes that may lead to huge performance gains. Specially in 1 line data access functions, like the accessors used in Object Oriented code.
The cost is that usually that will result in larger code, what might hurt performance. This is why setting a function to inline is only a "green flag" to the compiler, that it does not need to follow. The compiler will try to do what is best.
As a rule of thumb for beginners that don't want to deal with linkage peculiarities. inline function are to be called by other function in same compilation units. If you want to implement an inline function that can be used on multiple compilation units, make it an header file declared and implemented inline function.
Why?
Example: at header file inlinetest.h
int foo();
inline int bar();
At the compilation unit inlinetest.cpp
int foo(){ int r = bar(); return r; }
inline int bar(){ return 5;};
Then at the main.cpp
#include "inlinetest.h"
int main()
{
foo();
//bar();
}
Compile one object file at a time. If you uncomment that "bar" call you will have an error. Because the inline function is only implemented on the inlinetest.o object file and is not exported. At same time the foo function, very likely has embedded on it the code of the bar function (since bar is single line no I/O operation then its very likely to be inlined)
But if at the header file you had declared the inline function and implemented it inline then you would be able to use it at any compilation unit that includes that header.
("code sample");
Remove the inline keyword and compiler will NOT cause the error even with bar call at main And no inline will happen unless you ask the compiler to inline all functions. That is not standard behavior on most compilers.