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.
Related
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.
Let's imagine a blah.h header file that contains:
// A declaration without any code. We force inline
__attribute__((always_inline)) void inline_func();
And a blah.cpp source file that contains:
#include "blah.h"
// The code of the inline function
void inline_func() {
...
}
// Use the inline function
void foo() {
inline_func();
}
The question is, will the compiler actually inline the inline_func()? Should the code be with the declaration or they can be separate?
Assume no LTO
Note the (GCC) force inline decoration in inline_func()
Inlining is a two-step process:
* Is it possible?
* Is it worthwhile?
The first step is fairly trivially decided by the compiler, the second is a far more complex heuristic. Thus it makes sense to only consider the benefits of possible optimizations.
always_inline means that the second step is ignored. It does not affect the first consideration. Now, you've also stated that LTO is disabled, which means that first consideration, the ability for inlining, is restricted. This shows that LTO and always_inline are pretty unrelated since they affect two different inlining considerations.
Not that LTO matters for your example anyway. The two functions under consideration are in the same Translation Unit. There appear to be no other restrictions such as recursion, library calls, or other observable side effects. That means it should be possible to inline, and since that's the only consideration, it should be inlined.
You need to have the body available at the time the inlining is supposed to happen.
I.e. if you have the following files:
inlineFunc.h
inlineFunc.c
main.c
And you compile with:
compile inline.c
compile main.c
link innline.o mcompile inline.c
compile main.c
link innline.o main.o yourCoookProgramain.o yourCoookProgram
there is no way that inlineFunc gets inlined in main.c however calls to inlineFunc in inlineFunc.c can be inlined.
As Paolo mentioned, inline is only a hint to a compiler however some compilers also have ways to force the inining, i.e. for gcc you can use __attribute__(always_inline). Take alook here for a discussion on how gcc handles inlining.
An interesting sitenote:
The warning is issued in this case as the definition of foo() is not
available when main() is compiled. However, with -O2 or better
optimizations, gcc performs a kind of "backward inlining", meaning
that even function definitions that are further ahead in the source
file can be embedded into a caller. Consequently, the warning
disappears as soon as one uses at least -O2 optimizations. Is there
any specific option responsible for this behavior? I would like to
enable "backward inlining" even with -O1 or -O0.
Well, it depends. In your example, it will be inlined, because the definition of the function is in the same translation unit where it is used.
Otherwise, if no LTO is possible, and at compile time the definition of the function is not available to the compiler, then no, the function will not be inlined.
Prior answer
The answer is: it depends. It depends on the compiler, and it may depend on compiler's configuration(1)(2) too.
See also inline description at cppreference.com (quoted below):
The intent of the inline keyword is to serve as an indicator to the optimizer that inline substitution of the function is preferred over function call, that is, instead of executing the call CPU instruction to transfer control to the function body, a copy of the function body is executed without generating the call. This avoids extra overhead created by the function call (copying the arguments and retrieving the result) but it may result in a larger executable as the code for the function has to be repeated multiple times.
Since this meaning of the keyword inline is non-binding, compilers are free to use inline substitution for any function that's not marked inline, and are free to generate function calls to any function marked inline. Those choices do not change the rules regarding multiple definitions and shared statics listed above.
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.
I have been running into strange linking behavior with g++, however, I'm just a student, and I was wondering if this was normal.
I am trying to link assembly code (machine: fedora 14 gnome 32bits x86 i686 intel i7) with c++ code and to have the assembly code call a method from a fonction instanciated in the c++ file. It seems that implementing a method in the class declaration will prevent it from being put in the linker table unless it's used at least once in the original source.
class A
{
public:
void showSUP() {
cout<<"sup";
}
};
After instanciating A, you will not be able to call _ZN1A7showSUPEv because it has not been put in the linking table:
call _ZN1A7showSUPEv
However, if you call A::showSUP() in the same .cpp as A was declared, then calling it from a seperate assembly file will work.
With (and instantiation of A)
class A
{
void showSUP();
};
A::showSUP()
{
cout<<"sup";
}
Calling _ZN1A7showSUPEv will work.
My question is, why doesn't the first example work.
Thank you all in advance.
There are attributes, that you can specifify for a function in this way
classe A
{
public:
void showSUP(){
cout<<"sup";
} __attribute__((used))
};
see gcc attribute overview
used
Found in versions: 3.1-3.4
Description:
This attribute, attached to a function, means that code must be
emitted for the function even if it appears that the function is
not referenced. This is useful, for example, when the function
is
referenced only in inline assembly.
For inlined functions the compiler
will only output code where the function is used.
Functions defined
inside the class definition are
inline (usually).
The function isn't
used.
Therefore: no function in the
binary.
In general, if you want a function to be included in the final library / executable, it need be:
used
non-inlined
And inlined function is a function whose code is simply copied and pasted where the function is used (by the compiler) so that there is no function call. It's an opportunity optimization, so a function may be inlined in some places and not inlined in others, depending on the context. Most very short functions (so-called one-liners) are generally inlined.
In the old times, to be inlined a function needed be defined in the current translation unit, that is:
either it is defined in the header (like is your case), and thus can be inlined in all sources including this header
either it is defined in a source file, and thus can be inlined in this source file
Nowadays though we also have LTO (Link Time Optimization), and if activated the linker may actually inline function calls. Those optimizations are also responsible for cleaning up the resulting library/binary from unused symbols.
There are two possible solutions to your issue:
define the function in a source file instead, it is standard and may not be wiped out
use compiler specific attributes to mark the function as used, so that it's not wiped out
In the latter case, if you wish for portability, I can only advise using a macro (ATTRIBUTE_USED) and define its content depending on the current compiler used.
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