Symbol emission for inlined private member functions - c++

Suppose the following dummy header-source pair gets compiled into a single translation unit, as one would expect.
struct foo {
public:
int bar(int x);
private:
int baz();
};
int foo::bar(int x) {
return baz() * 2 - 1;
}
int foo::baz() {
return 42;
}
In every compiler I've used so far, foo::baz() is short enough that it gets inlined into foo::bar(int), which is expected. However every single one of them still emits an out-of-line copy of the function, even though in reality it would never be accessible from outside the class (unless the raw symbol is referenced directly or something, as C++ member visibility != symbol visibility). This occurs even with -fvisibility=hidden (on compilers that support this flag).
This is partly why I often like to enable LTO because it has the nice side-effect that it will automatically preen (or not emit in the first place) functions like that when they get inlined and never referenced as a symbol (because it would know that hidden symbols that never get referenced anywhere in the binary being linked ought not be emitted at all). With these two things enabled, foo::baz() does not get emitted, which is what I want. However, LTO is not something I can enable in every project for one reason or another. My question is thus how to encourage the compiler to not emit these functions without the help of something like LTO.
For context, I am mostly interested in GCC and GCC-like compilers like Clang and MinGW, but if there is a compiler independent way, that would be even better.
Speaking of which, one could use a static non-member function, which will not be emitted out-of-line if it is ever inlined such that an out-of-line copy would never be referenced, but that seems like a rather clunky way to circumvent this problem for obvious reasons (e.g. accessing private members would be more cumbersome). Besides, it's not always my code that is being compiled, so I'd want to mitigate this problem when compiling other people's code, too.
In general, all this is not really a big problem, as such functions, when emitted out-of-line, are probably small or trivial enough that they would be inlined in the first place, and thus would probably not be that big of a waste of space at all in the binary file. Still, it does feel like a bit of extra bits that could use some trimming off.
See here for example source code.

Related

Declare member function inline without inlining it [duplicate]

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.

Why `-fvisibility-inlines-hidden` is not the default?

I am asking to see whether my understandings are correct.
inline is a suggestion to C++ compiler for substituting a function whenever it sees better, therefore calling a procedure flagged as inlined from outside of a library shouldn't be reliable and they logically should be hidden by default, preventing others to call them as an update to a compiler or codebase can be change the decision (thus removal of the inlined function and ABI breakage?).
However it seems that is not the default setting and -fvisibility-inlines-hidden should be set to make that happen. I am asking here why that is the case? Does not setting that has any real use case and it is there just because legacy reasons?
they logically should be hidden by default
C++ requires all functions (including inline functions) to have the same address in all translation units. Local statics should also be shared among all translation units. Making inline functions hidden violates those requirements if program is built as multiple shared objects (.so files).
Inline functions should have public visibility so that dynamic linker could choose one definition from all existing ones at runtime.
GCC wiki mentions this:
-fvisibility-inlines-hidden can be used with no source alterations, unless you need to override it for inlines where address identity is important either for the function itself or any function local static data.
Consider following example. Executable source:
// main.cpp
#include <cstdio>
struct A { };
inline A &foo()
{
static A a;
return a;
}
int main()
{
void *p = &foo();
std::printf("main() - %p\n", p);
}
Shared object source:
#include <cstdio>
struct A { };
inline A &foo()
{
static A a;
return a;
}
static __attribute__((constructor)) void init()
{
void *p = &foo();
std::printf("main() - %p\n", p);
}
If you build both and link executable against this shared object, you can see that foo always returns the same address in both translation units.
Now if you add __attribute__((visibility("hidden"))) to those inline functions, then you will see that address is different in different translation units.
This is not what some C++ program might expect.
Most people today think that inline has nothing to do with actual function inlining. This is not exactly true. ELF targets try to make dynamic linking transparent e.g. program should behave identically if it is build as a single executable or as multiple shared objects.
To make it possible ELF requires all functions with public visibility to be called though GOT or through PLT as if it is "imported" function. This is required so that every function could be overriden by another library (or executable itself). This also forbids inlining for all public non-inline functions (see section 3.5.5 here which shows that public function call in PIC should be made through PLT).
Code inlining for public inline functions is possible exactly because inline allows program behavior to be undefined when multiple definitions of inline function are not equivalent.
Interesting note: Clang violates this ELF requirement and is able to inline public functions on ELF targets anyway. GCC can do the same with -fno-semantic-interposition flag.
inline is a suggestion to C++ compiler for substituting a function whenever it sees better
No. This was originally the case, in perhaps the late 90s, but has not been true for a long time.
See this answer for a good explanation.
therefore calling a procedure flagged as inlined from outside of a library shouldn't be reliable
your initial assumption is already wrong, so the therefore is proceeding from a false premise
even if the compiler does inline a call (which it may do with or without the inline keyword), this is done at a specific call site. Inlining isn't something that happens to a function, which must always be emitted as usual, but to a function call.
It's entirely possible for the compiler to inline some calls to a function and not others, depending on its opinion of what will produce the best code at the call site.
Now, it's not clear what problem you believe inline causes in libraries, so it's hard to address that directly.
inline is a suggestion to C++ compiler for substituting a function whenever it sees better, therefore calling a procedure flagged as inlined from outside of a library shouldn't be reliable and they logically should be hidden by default
The compiler can still decide to inline some calls and leave some of them non-inlined. In this case you would get several copy of the inlined function in all the libraries you are linking together.
Moreover the standard somewhat requires that &foo to be the same address everywhere in your program, although the standard does not say anything about DSO/DLLs, so the compilers have some freedom in those regards (in fact, MSVC follows the opposite approach of leaving everything hidden by default).
However it seems that is not the default setting and -fvisibility-inlines-hidden should be set to make that happen.
Despite the name, -fvisibility-inlines-hidden only affects inlined class member functions. For everything else, -fvisibility=hidden should be sufficient.
Does not setting that has any real use case and it is there just because legacy reasons?
Yes. IIRC that flag was implemented in GCC 3.2 (or close enough); making it default would break a lot of legacy code.

Moving inline methods from a header file to a .cpp files

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.

Why main() in C++ cannot be inlined?

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.

What Does It Mean For a C++ Function To Be Inline?

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.