static implies inline or vice versa or both? - c++

For free (NOT inside classes) functions:
static implies inline?
inline implies static?
Or both?
Considering examples:
static void foo1() { ... };
static inline void foo2 { ... };
inline void foo3() { ... };
What the difference?

There are differences, consider (in header):
static int foo1() { static int i = 0; return ++i; }
static inline int foo2() { static int i = 0; return ++i; }
inline int foo3() { static int i = 0; return ++i; }
and in 2 cpp "void caller[1-2]_foo[1-3]() { std::cout << foo[1-3]() << std::endl; }".
So
int main()
{
caller1_foo1(); // 1
caller2_foo1(); // 1
caller1_foo2(); // 1
caller2_foo2(); // 1
caller1_foo3(); // 1
caller2_foo3(); // 2
}
Demo
I cannot found differences between static and static inline though.

No, inline does not imply static not vice versa. See inline nad static description.

(S) Static tells the compiler that the code is only used from this module. You may even get an "unused" warning if you don't use it.
(I) Inline tells the compiler to "try harder" to inline the code. It is not a guarantee, either way, but compilers have various options and pragmas to control this.
If the compiler decides to inline it in this module, then everyone is happy. If the method is also used in another (source) module, that module will decide for itself what to do.
(sI) If the compiler decides not to inline the non-static function, then it will exist as a stand-alone function.
(SI) The presence of 'static' has an effect. If it is static, the name is not emitted to the linker: another module would generate another function with the same name, perhaps from the same source, perhaps not. If it is not static then the compiler will emit the symbol to the linker. If another module also decides not to inline, then it will be emitted twice, and the linker handles this by just picking one (seemingly at random for dynamic linking)!
(Si) Use of static duplication can improve code locality, where non-static code pays for non-locality in all but 1 call. Non-locality is not really a big issue, however. This does also apply to inline tagged methods the compiler decides not to inline.
(si) Note that a non-static non-inline function that the compiler decides to inline anyway has to be emitted as a non-inlined function to the linker as well as the inlined code, in case some other module should extern to it. The linker can discard this function if it is not referenced externally (or exported)
Does it make much difference? probably not!

Related

static inline function in C++ headers [duplicate]

There are two implications of using the inline keyword(§ 7.1.3/4):
It hints the compiler that substitution of function body at the point of call is preferable over the usual function call mechanism.
Even if the inline substitution is omitted, the other rules(especially w.r.t One Definition Rule) for inline are followed.
Usually any mainstream compiler will substitute function body at the point of call if needed, so marking function inline merely for #1 is not really needed.
Further w.r.t #2, As I understand when you declare a function as static inline function,
The static keyword on the function forces the inline function to have an internal linkage(inline functions have external linkage) Each instance of such a function is treated as a separate function(address of each function is different) and each instance of these functions have their own copies of static local variables & string literals(an inline function has only one copy of these)
Thus such a function acts like any other static function and the keyword inline has no importance anymore, it becomes redundant.
So, Practically marking a function static and inline both has no use at all. Either it should be static(not most preferred) or inline(most preferred),
So, Is using static and inline together on a function practically useless?
Your analysis is correct, but doesn't necessarily imply uselessness. Even if most compilers do automatically inline functions (reason #1), it's best to declare inline just to describe intent.
Disregarding interaction with inline, static functions should be used sparingly. The static modifier at namespace scope was formerly deprecated in favor of unnamed namespaces (C++03 §D.2). For some obscure reason that I can't recall it was removed from deprecation in C++11 but you should seldom need it.
So, Practically marking a function static and inline both has no use at all. Either it should be static(not most preferred) or inline(most preferred),
There's no notion of preference. static implies that different functions with the same signature may exist in different .cpp files (translation units). inline without static means that it's OK for different translation units to define the same function with identical definitions.
What is preferred is to use an unnamed namespace instead of static:
namespace {
inline void better(); // give the function a unique name
}
static inline void worse(); // kludge the linker to allowing duplicates
Static and inline are orthogonal (independent). Static means the function should not be visible outside of the translation unit, inline is a hint to the compiler the programmer would like to have this function inlined. Those two are not related.
Using static inline makes sense when the inlined function is not used outside of the translation unit. By using it you can prevent a situation of accidental violation of ODR rule by naming another inlined function in another tranlation unit with the same name.
Example:
source1.cpp:
inline int Foo()
{
return 1;
}
int Bar1()
{
return Foo();
}
source2.cpp:
inline int Foo()
{
return 2;
}
int Bar2()
{
return Foo();
}
Without using static on Foo (or without using an anonymous namespace, which is preferred way by most C++ programmers), this example violates ODR and the results are undefined. You can test with Visual Studio the result of Bar1/Bar2 will depend on compiler settings - in Debug configuration both Bar1 and Bar2 will return the same value (inlining not used, one implementation selected randomly by the linker), in Release configuration each of them will return the intended value.
I may not be completely right about this, but as far as I know declaring a function static inline is the only way to make (or allow) the compiler to generate a machine code where the function really is not defined in the compiled code at all, and all you have is a direct substitution of the function call into a sequence of instructions, like it were just a regular procedure body, with no trace in the machine code of a procedure call relative to that function definition from the source code.
That is, only with static inline you can really substitute the use of a macro, inline by itself is not enough.
A simple Google search for "static inline" will show you compiler documentation pages that talk about it. I guess this should be enough to answer your question, and say, "no, it is not practically useless". Here is one example of a site discussing the use of inline, and specifically of static inline http://www.greenend.org.uk/rjk/tech/inline.html
If you talk about free functions (namespace scope), then your assumption is correct. static inline functions indeed don't have much value. So static inline is simply a static function, which automatically satisfies ODR and inline is redundant for ODR purpose.
However when we talk about member methods (class scope), the static inline function does have the value.
Once you declare a class method as inline, it's full body has to be visible to all translation units which includes that class.
Remember that static keyword has a different meaning when it comes for a class.
Edit: As you may know that static function inside a class doesn't have internal linkage, in other words a class cannot have different copies of its static method depending on the translation (.cpp) units.
But a free static function at namespace/global scope does have different copies per every translation unit.
e.g.
// file.h
static void foo () {}
struct A {
static void foo () {}
};
// file1.cpp
#include"file.h"
void x1 ()
{
foo(); // different function exclusive to file1.cpp
A::foo(); // same function
}
// file2.cpp
#include"file.h"
void x2 ()
{
foo(); // different function exclusive to file2.cpp
A::foo(); // same function
}
I just read a man page for gcc and it specifically states the use of static inline with a compiler flag. In the case of the flag, it inlines the function and if it is also static and is inlined in every instance that it is called, then it gets rid of the function definition which will never be used in the created object file, thereby reducing the size of the generated code by that little bit.

Inline function in c++ understanding the meaning of inline function [duplicate]

When should I write the keyword inline for a function/method in C++?
After seeing some answers, some related questions:
When should I not write the keyword 'inline' for a function/method in C++?
When will the compiler not know when to make a function/method 'inline'?
Does it matter if an application is multithreaded when one writes 'inline' for a function/method?
Oh man, one of my pet peeves.
inline is more like static or extern than a directive telling the compiler to inline your functions. extern, static, inline are linkage directives, used almost exclusively by the linker, not the compiler.
It is said that inline hints to the compiler that you think the function should be inlined. That may have been true in 1998, but a decade later the compiler needs no such hints. Not to mention humans are usually wrong when it comes to optimizing code, so most compilers flat out ignore the 'hint'.
static - the variable/function name cannot be used in other translation units. Linker needs to make sure it doesn't accidentally use a statically defined variable/function from another translation unit.
extern - use this variable/function name in this translation unit but don't complain if it isn't defined. The linker will sort it out and make sure all the code that tried to use some extern symbol has its address.
inline - this function will be defined in multiple translation units, don't worry about it. The linker needs to make sure all translation units use a single instance of the variable/function.
Note: Generally, declaring templates inline is pointless, as they have the linkage semantics of inline already. However, explicit specialization and instantiation of templates require inline to be used.
Specific answers to your questions:
When should I write the keyword 'inline' for a function/method in C++?
Only when you want the function to be defined in a header. More exactly only when the function's definition can show up in multiple translation units. It's a good idea to define small (as in one liner) functions in the header file as it gives the compiler more information to work with while optimizing your code. It also increases compilation time.
When should I not write the keyword 'inline' for a function/method in C++?
Don't add inline just because you think your code will run faster if the compiler inlines it.
When will the compiler not know when to make a function/method 'inline'?
Generally, the compiler will be able to do this better than you. However, the compiler doesn't have the option to inline code if it doesn't have the function definition. In maximally optimized code usually all private methods are inlined whether you ask for it or not.
As an aside to prevent inlining in GCC, use __attribute__(( noinline )), and in Visual Studio, use __declspec(noinline).
Does it matter if an application is multithreaded when one writes 'inline' for a function/method?
Multithreading doesn't affect inlining in any way.
I'd like to contribute to all of the great answers in this thread with a convincing example to disperse any remaining misunderstanding.
Given two source files, such as:
inline111.cpp:
#include <iostream>
void bar();
inline int fun() {
return 111;
}
int main() {
std::cout << "inline111: fun() = " << fun() << ", &fun = " << (void*) &fun;
bar();
}
inline222.cpp:
#include <iostream>
inline int fun() {
return 222;
}
void bar() {
std::cout << "inline222: fun() = " << fun() << ", &fun = " << (void*) &fun;
}
Case A:
Compile:
g++ -std=c++11 inline111.cpp inline222.cpp
Output:
inline111: fun() = 111, &fun = 0x4029a0
inline222: fun() = 111, &fun = 0x4029a0
Discussion:
Even thou you ought to have identical definitions of your inline
functions, C++ compiler does not flag it if that is not the case (actually, due to separate compilation it has no ways to check it). It is your own duty to ensure this!
Linker does not complain about One Definition Rule, as fun() is declared as inline. However, because inline111.cpp is the first translation unit (which actually calls fun()) processed by compiler, the compiler instantiates fun() upon its first call-encounter in inline111.cpp. If compiler decides not to expand fun() upon its call from anywhere else in your program (e.g. from inline222.cpp), the call to fun() will always be linked to its instance produced from inline111.cpp (the call to fun() inside inline222.cpp may also produce an instance in that translation unit, but it will remain unlinked). Indeed, that is evident from the identical &fun = 0x4029a0 print-outs.
Finally, despite the inline suggestion to the compiler to actually expand the one-liner fun(), it ignores your suggestion completely, which is clear because fun() = 111 in both of the lines.
Case B:
Compile (notice reverse order):
g++ -std=c++11 inline222.cpp inline111.cpp
Output:
inline111: fun() = 222, &fun = 0x402980
inline222: fun() = 222, &fun = 0x402980
Discussion:
This case asserts what have been discussed in Case A.
Notice an important point, that if you comment out the actual call to fun() in inline222.cpp (e.g. comment out cout-statement in inline222.cpp completely) then, despite the compilation order of your translation units, fun() will be instantiated upon it's first call encounter in inline111.cpp, resulting in print-out for Case B as inline111: fun() = 111, &fun = 0x402980.
Case C:
Compile (notice -O2):
g++ -std=c++11 -O2 inline222.cpp inline111.cpp
or
g++ -std=c++11 -O2 inline111.cpp inline222.cpp
Output:
inline111: fun() = 111, &fun = 0x402900
inline222: fun() = 222, &fun = 0x402900
Discussion:
As is described here, -O2 optimization encourages compiler to actually expand the functions that can be inlined (Notice also that -fno-inline is default without optimization options). As is evident from the outprint here, the fun() has actually been inline expanded (according to its definition in that particular translation unit), resulting in two different fun() print-outs. Despite this, there is still only one globally linked instance of fun() (as required by the standard), as is evident from identical &fun print-out.
You still need to explicitly inline your function when doing template specialization (if specialization is in .h file)
1) Nowadays, pretty much never. If it's a good idea to inline a function, the compiler will do it without your help.
2) Always. See #1.
(Edited to reflect that you broke your question into two questions...)
When should I not write the keyword 'inline' for a function/method in C++?
If the function is declared in the header and defined in the .cpp file, you should not write the keyword.
When will the the compiler not know when to make a function/method 'inline'?
There is no such situation. The compiler cannot make a function inline. All it can do is to inline some or all calls to the function. It can't do so if it hasn't got the code of the function (in that case the linker needs to do it if it is able to do so).
Does it matter if an application is multithreaded when one writes 'inline' for a function/method?
No, that does not matter at all.
When will the the compiler not know when to make a function/method 'inline'?
This depends on the compiler used. Do not blindly trust that nowadays compilers know better then humans how to inline and you should never use it for performance reasons, because it's linkage directive rather than optimization hint. While I agree that ideologically are these arguments correct encountering reality might be a different thing.
After reading multiple threads around I tried out of curiosity the effects of inline on the code I'm just working and the results were that I got measurable speedup for GCC and no speed up for Intel compiler.
(More detail: math simulations with few critical functions defined outside class, GCC 4.6.3 (g++ -O3), ICC 13.1.0 (icpc -O3); adding inline to critical points caused +6% speedup with GCC code).
So if you qualify GCC 4.6 as a modern compiler the result is that inline directive still matters if you write CPU intensive tasks and know where exactly is the bottleneck.
In reality, pretty much never. All you're doing is suggesting that the compiler make a given function inline (e.g., replace all calls to this function /w its body). There are no guarantees, of course: the compiler may ignore the directive.
The compiler will generally do a good job of detecting + optimizing things like this.
gcc by default does not inline any functions when compiling without
optimization enabled. I don't know about visual studio – deft_code
I checked this for Visual Studio 9 (15.00.30729.01) by compiling with /FAcs and looking at the assembly code:
The compiler produced calls to member functions without optimization enabled in debug mode. Even if the function is marked with __forceinline, no inline runtime code is produced.
F.5: If a function is very small and time-critical, declare it inline
Reason: Some optimizers are good at inlining without hints from the programmer, but don’t rely on it. Measure! Over the last 40 years or so, we have been promised compilers that can inline better than humans without hints from humans. We are still waiting. Specifying inline (explicitly, or implicitly when writing member functions inside a class definition) encourages the compiler to do a better job.
Source: https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines.html#Rf-inline
For examples and exceptions, go to the Source (see above).
One use case might occur on inheritance. For example, if all below cases are true:
you have a base class of some class
the base class needs to be abstract
the base class has no pure virtual method other than destructor
you don't want to create cpp file for the base class because in vain
then you have to define the destructor; otherwise, you will have some undefined referance linker errors. Moreover, you have to do not only define but also to define the destructor with inline keyword; otherwise, you will have multiple definition linker errors.
This may happen for some helper classes that contains only static methods or writing base exception classes etc.
Let's give an example:
Base.h:
class Base {
public:
Base(SomeElementType someElement) noexcept : _someElement(std::move(someElement)) {}
virtual ~Base() = 0;
protected:
SomeElementType _someElement;
}
inline Base::~Base() = default;
Derived1.h:
#include "Base.h"
class Derived1 : public Base {
public:
Derived1(SomeElementType someElement) noexcept : Base(std::move(someElement)) {}
void DoSomething1() const;
}
Derived1.cpp:
#include "Derived1.h"
void Derived1::DoSomething1() const {
// use _someElement
}
Derived2.h:
#include "Base.h"
class Derived2 : public Base {
public:
Derived2(SomeElementType someElement) noexcept : Base(std::move(someElement)) {}
void DoSomething2() const;
}
Derived2.cpp:
#include "Derived2.h"
void Derived2::DoSomething2() const {
// use _someElement
}
Generally, abstract classes have some pure virtual methods other than constructor or destructor. So, you didn't have to seperate decleration and definition of virtual destructor of the base class, you could just write virtual ~Base() = default; on class decleration. However, in our case it's not like that.
As far as I know, MSVC allow you to write something like that on class decleration: virtual ~Base() = 0 {}. So you don't need to seperate decleration and definition with inline keyword. But it will only work with MSVC compiler.
Real world example:
BaseException.h:
#pragma once
#include <string>
class BaseException : public std::exception {
public:
BaseException(std::string message) noexcept : message(std::move(message)) {}
virtual char const* what() const noexcept { return message.c_str(); }
virtual ~BaseException() = 0;
private:
std::string message;
};
inline BaseException::~BaseException() = default;
SomeException.h:
#pragma once
#include "BaseException.h"
class SomeException : public BaseException {
public:
SomeException(std::string message) noexcept : BaseException(std::move(message)) {}
};
SomeOtherException.h:
#pragma once
#include "BaseException.h"
class SomeOtherException : public BaseException {
public:
SomeOtherException(std::string message) noexcept : BaseException(std::move(message)) {}
};
main.cpp:
#include <SomeException.h>
#include <SomeOtherException.h>
#include <iostream>
using namespace std;
static int DoSomething(int argc) {
try {
switch (argc) {
case 0:
throw SomeException("some");
case 1:
throw SomeOtherException("some other");
default:
return 0;
}
}
catch (const exception& ex) {
cout << ex.what() << endl;
return 1;
}
}
int main(int argc, char**) {
return DoSomething(argc);
}
Unless you are writing a library or have special reasons, you can forget about inline and use link-time optimization instead. It removes the requirement that a function definition must be in a header for it to be considered for inlining across compilation units, which is precisely what inline allows.
(But see Is there any reason why not to use link time optimization?)
C++ inline is totally different to C inline.
#include <iostream>
extern inline int i[];
int i [5];
struct c {
int function (){return 1;} // implicitly inline
static inline int j = 3; // explicitly inline
static int k; // without inline, a static member has to be defined out of line
static int f (){return 1;} // but a static method does not // implicitly inline
};
extern inline int b;
int b=3;
int c::k = 3; // when a static member is defined out of line it cannot have a static
// specifier and if it doesn't have an `inline` specifier in the
// declaration or on the definition then it is not inline and always
// emits a strong global symbol in the translation unit
int main() {
c j;
std::cout << i;
}
inline on its own affects the compiler, assembler and the linker. It is a directive to the compiler saying only emit a symbol for this function/data if it's used in the translation unit, and if it is, then like class methods, tell the assembler to store them in the section .section .text.c::function(),"axG",#progbits,c::function(),comdat or .section .bss.i,"awG",#nobits,i,comdat for unitialised data or .section .data.b,"awG",#progbits,b,comdat for initialised data. Template instantiations also go in their own comdat groups.
This follows .section name, "flags"MG, #type, entsize, GroupName[, linkage]. For instance, the section name is .text.c::function(). axG means the section is allocatable, executable and in a group i.e. a group name will be specified (and there is no M flag so no entsize will be specified); #progbits means the section contains data and isn't blank; c::function() is the group name and the group has comdat linkage meaning that in all object files, all sections encountered with this group name tagged with comdat will be removed from the final executable except for 1 i.e. the compiler makes sure that there is only one definition in the translation unit and then tells the assembler to put it in its own group in the object file (1 section in 1 group) and then the linker will make sure that if any object files have a group with the same name, then only include one in the final .exe. The difference between inline and not using inline is now visible to the assembler and as a result the linker, because it's not stored in the regular .data or .text etc by the assembler due to their directives. Only inline symbols with external linkage are given external comdat linkage like this -- static linkage (local) symbols do not need to go in comdat groups.
inline on a non-static method declaration in a class makes the method inline if it is defined out-of-line, this will prevent the method being emitted in the translation unit if it is not referenced in the translation unit. The same effect is achieved by putting inline on the out-of-line definition. When a method is defined out-of-line without an inline specifier and the declaration in the class is not inline then it will emit a symbol for the method in the translation unit at all times because it will have external linkage rather than external comdat linkage. If the method is defined in the class then it is implicitly inline, which gives it external comdat linkage rather than external linkage.
static inline on a member in a class (as opposed to method) makes it a static member (which does not refer to its linkage -- it has the linkage of its class which may be extern). static inline also allows static members of the class to be defined inside the class instead of needing to be declared in the class and then defined out-of-line (without static in the definition, which wasn't allowed without -fpermissive). *static inline* also makes the members inline and not static inline -- inline means that the definition is only emitted if it is referenced in the translation unit. Previously you had to specify inline on the out-of-line definition to make the member inline.
Seeing as static methods can be defined in the class, static inline has no effect on the static method defined in the class, which always has external linkage, is a static method and is inline. If it is defined out of line then inline must be used to make it inline (i.e. to give to external comdat linkage rather than just external linkage), and static still can't be used.
static inline at file scope only affects the compiler. It means to the compiler: only emit a symbol for this function/data if it's used in the translation unit and do so as a regular static symbol (store in.text /.data without .globl directive). To the assembler there is now no difference between static and static inline. Like the other forms of inline, it cannot be used on a class, which is a type, but can be used on an object of the type of that class. This form of static inline also cannot be used on members or methods of a function, where it will always be treated inline as the static means something else in a class (it means that the class is acting as a scope rather than it being a member of or method to be used on an object).
extern inline is a declaration that means you must define this symbol in the translation unit if it is referenced or throw compiler error; if it's defined then treat it as a regular inline and to the assembler and linker there will be no difference between extern inline and inline, so this is a compiler guard only.
extern inline int i[];
extern int i[]; //allowed repetition of declaration with incomplete type, inherits inline property
extern int i[5]; //declaration now has complete type
extern int i[5]; //allowed redeclaration if it is the same complete type or has not yet been completed
extern int i[6]; //error, redeclaration with different complete type
int i[5]; //definition, must have complete type and same complete type as the declaration if there is a declaration with a complete type
The whole of the above without the error line collapses to inline int i[5]. Obviously if you did extern inline int i[] = {5}; then extern would be ignored due to the explicit definition through assignment.
I think the reason that static is not allowed on a static out-of-line definition without -fpermissive is because it implies that the static refers to static linkage, because it's not immediately obvious to the programmer that it is a member of a class or whether that class has , where the static means something different. -fpermissive ignores the static specifier on the out-of-line definition and it means nothing. In the case of a simple integer, k can't be defined out of a namespace, if c were a namespace, but if k were a function, then there would be no way of visibly telling from the line of code whether it is an out of line definition of a function in a namespace with static linkage, or an out-of-line definition of a static member with external linkage, and may give the wrong impression to the programmer / reader of the code.
For local classes, inline on a member / method will result in a compiler error and members and methods have no linkage.
For inline on a namespace, see this and this
Inline keyword requests the compiler to replace the function call with the body of the function ,it first evaluates the expression and then passed.It reduces the function call overhead as there is no need to store the return address and stack memory is not required for function arguments.
When to use:
To Improve performance
To reduce call overhead .
As it's just a request to the compiler, certain functions won't be inlined
*large functions
functions having too many conditional arguments
recursive code and code with loops etc.
You want to put it in the very beginning, before return type. But most Compilers ignore it. If it's defined, and it has a smaller block of code, most compilers consider it inline anyway.
When developing and debugging code, leave inline out. It complicates debugging.
The major reason for adding them is to help optimize the generated code. Typically this trades increased code space for speed, but sometimes inline saves both code space and execution time.
Expending this kind of thought about performance optimization before algorithm completion is premature optimization.
When one should inline :
1.When one want to avoid overhead of things happening when function is called like parameter passing , control transfer, control return etc.
2.The function should be small,frequently called and making inline is really advantageous since as per 80-20 rule,try to make those function inline which has major impact on program performance.
As we know that inline is just a request to compiler similar to register and it will cost you at Object code size.

Inlining functions within class definition [duplicate]

When should I write the keyword inline for a function/method in C++?
After seeing some answers, some related questions:
When should I not write the keyword 'inline' for a function/method in C++?
When will the compiler not know when to make a function/method 'inline'?
Does it matter if an application is multithreaded when one writes 'inline' for a function/method?
Oh man, one of my pet peeves.
inline is more like static or extern than a directive telling the compiler to inline your functions. extern, static, inline are linkage directives, used almost exclusively by the linker, not the compiler.
It is said that inline hints to the compiler that you think the function should be inlined. That may have been true in 1998, but a decade later the compiler needs no such hints. Not to mention humans are usually wrong when it comes to optimizing code, so most compilers flat out ignore the 'hint'.
static - the variable/function name cannot be used in other translation units. Linker needs to make sure it doesn't accidentally use a statically defined variable/function from another translation unit.
extern - use this variable/function name in this translation unit but don't complain if it isn't defined. The linker will sort it out and make sure all the code that tried to use some extern symbol has its address.
inline - this function will be defined in multiple translation units, don't worry about it. The linker needs to make sure all translation units use a single instance of the variable/function.
Note: Generally, declaring templates inline is pointless, as they have the linkage semantics of inline already. However, explicit specialization and instantiation of templates require inline to be used.
Specific answers to your questions:
When should I write the keyword 'inline' for a function/method in C++?
Only when you want the function to be defined in a header. More exactly only when the function's definition can show up in multiple translation units. It's a good idea to define small (as in one liner) functions in the header file as it gives the compiler more information to work with while optimizing your code. It also increases compilation time.
When should I not write the keyword 'inline' for a function/method in C++?
Don't add inline just because you think your code will run faster if the compiler inlines it.
When will the compiler not know when to make a function/method 'inline'?
Generally, the compiler will be able to do this better than you. However, the compiler doesn't have the option to inline code if it doesn't have the function definition. In maximally optimized code usually all private methods are inlined whether you ask for it or not.
As an aside to prevent inlining in GCC, use __attribute__(( noinline )), and in Visual Studio, use __declspec(noinline).
Does it matter if an application is multithreaded when one writes 'inline' for a function/method?
Multithreading doesn't affect inlining in any way.
I'd like to contribute to all of the great answers in this thread with a convincing example to disperse any remaining misunderstanding.
Given two source files, such as:
inline111.cpp:
#include <iostream>
void bar();
inline int fun() {
return 111;
}
int main() {
std::cout << "inline111: fun() = " << fun() << ", &fun = " << (void*) &fun;
bar();
}
inline222.cpp:
#include <iostream>
inline int fun() {
return 222;
}
void bar() {
std::cout << "inline222: fun() = " << fun() << ", &fun = " << (void*) &fun;
}
Case A:
Compile:
g++ -std=c++11 inline111.cpp inline222.cpp
Output:
inline111: fun() = 111, &fun = 0x4029a0
inline222: fun() = 111, &fun = 0x4029a0
Discussion:
Even thou you ought to have identical definitions of your inline
functions, C++ compiler does not flag it if that is not the case (actually, due to separate compilation it has no ways to check it). It is your own duty to ensure this!
Linker does not complain about One Definition Rule, as fun() is declared as inline. However, because inline111.cpp is the first translation unit (which actually calls fun()) processed by compiler, the compiler instantiates fun() upon its first call-encounter in inline111.cpp. If compiler decides not to expand fun() upon its call from anywhere else in your program (e.g. from inline222.cpp), the call to fun() will always be linked to its instance produced from inline111.cpp (the call to fun() inside inline222.cpp may also produce an instance in that translation unit, but it will remain unlinked). Indeed, that is evident from the identical &fun = 0x4029a0 print-outs.
Finally, despite the inline suggestion to the compiler to actually expand the one-liner fun(), it ignores your suggestion completely, which is clear because fun() = 111 in both of the lines.
Case B:
Compile (notice reverse order):
g++ -std=c++11 inline222.cpp inline111.cpp
Output:
inline111: fun() = 222, &fun = 0x402980
inline222: fun() = 222, &fun = 0x402980
Discussion:
This case asserts what have been discussed in Case A.
Notice an important point, that if you comment out the actual call to fun() in inline222.cpp (e.g. comment out cout-statement in inline222.cpp completely) then, despite the compilation order of your translation units, fun() will be instantiated upon it's first call encounter in inline111.cpp, resulting in print-out for Case B as inline111: fun() = 111, &fun = 0x402980.
Case C:
Compile (notice -O2):
g++ -std=c++11 -O2 inline222.cpp inline111.cpp
or
g++ -std=c++11 -O2 inline111.cpp inline222.cpp
Output:
inline111: fun() = 111, &fun = 0x402900
inline222: fun() = 222, &fun = 0x402900
Discussion:
As is described here, -O2 optimization encourages compiler to actually expand the functions that can be inlined (Notice also that -fno-inline is default without optimization options). As is evident from the outprint here, the fun() has actually been inline expanded (according to its definition in that particular translation unit), resulting in two different fun() print-outs. Despite this, there is still only one globally linked instance of fun() (as required by the standard), as is evident from identical &fun print-out.
You still need to explicitly inline your function when doing template specialization (if specialization is in .h file)
1) Nowadays, pretty much never. If it's a good idea to inline a function, the compiler will do it without your help.
2) Always. See #1.
(Edited to reflect that you broke your question into two questions...)
When should I not write the keyword 'inline' for a function/method in C++?
If the function is declared in the header and defined in the .cpp file, you should not write the keyword.
When will the the compiler not know when to make a function/method 'inline'?
There is no such situation. The compiler cannot make a function inline. All it can do is to inline some or all calls to the function. It can't do so if it hasn't got the code of the function (in that case the linker needs to do it if it is able to do so).
Does it matter if an application is multithreaded when one writes 'inline' for a function/method?
No, that does not matter at all.
When will the the compiler not know when to make a function/method 'inline'?
This depends on the compiler used. Do not blindly trust that nowadays compilers know better then humans how to inline and you should never use it for performance reasons, because it's linkage directive rather than optimization hint. While I agree that ideologically are these arguments correct encountering reality might be a different thing.
After reading multiple threads around I tried out of curiosity the effects of inline on the code I'm just working and the results were that I got measurable speedup for GCC and no speed up for Intel compiler.
(More detail: math simulations with few critical functions defined outside class, GCC 4.6.3 (g++ -O3), ICC 13.1.0 (icpc -O3); adding inline to critical points caused +6% speedup with GCC code).
So if you qualify GCC 4.6 as a modern compiler the result is that inline directive still matters if you write CPU intensive tasks and know where exactly is the bottleneck.
In reality, pretty much never. All you're doing is suggesting that the compiler make a given function inline (e.g., replace all calls to this function /w its body). There are no guarantees, of course: the compiler may ignore the directive.
The compiler will generally do a good job of detecting + optimizing things like this.
gcc by default does not inline any functions when compiling without
optimization enabled. I don't know about visual studio – deft_code
I checked this for Visual Studio 9 (15.00.30729.01) by compiling with /FAcs and looking at the assembly code:
The compiler produced calls to member functions without optimization enabled in debug mode. Even if the function is marked with __forceinline, no inline runtime code is produced.
F.5: If a function is very small and time-critical, declare it inline
Reason: Some optimizers are good at inlining without hints from the programmer, but don’t rely on it. Measure! Over the last 40 years or so, we have been promised compilers that can inline better than humans without hints from humans. We are still waiting. Specifying inline (explicitly, or implicitly when writing member functions inside a class definition) encourages the compiler to do a better job.
Source: https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines.html#Rf-inline
For examples and exceptions, go to the Source (see above).
One use case might occur on inheritance. For example, if all below cases are true:
you have a base class of some class
the base class needs to be abstract
the base class has no pure virtual method other than destructor
you don't want to create cpp file for the base class because in vain
then you have to define the destructor; otherwise, you will have some undefined referance linker errors. Moreover, you have to do not only define but also to define the destructor with inline keyword; otherwise, you will have multiple definition linker errors.
This may happen for some helper classes that contains only static methods or writing base exception classes etc.
Let's give an example:
Base.h:
class Base {
public:
Base(SomeElementType someElement) noexcept : _someElement(std::move(someElement)) {}
virtual ~Base() = 0;
protected:
SomeElementType _someElement;
}
inline Base::~Base() = default;
Derived1.h:
#include "Base.h"
class Derived1 : public Base {
public:
Derived1(SomeElementType someElement) noexcept : Base(std::move(someElement)) {}
void DoSomething1() const;
}
Derived1.cpp:
#include "Derived1.h"
void Derived1::DoSomething1() const {
// use _someElement
}
Derived2.h:
#include "Base.h"
class Derived2 : public Base {
public:
Derived2(SomeElementType someElement) noexcept : Base(std::move(someElement)) {}
void DoSomething2() const;
}
Derived2.cpp:
#include "Derived2.h"
void Derived2::DoSomething2() const {
// use _someElement
}
Generally, abstract classes have some pure virtual methods other than constructor or destructor. So, you didn't have to seperate decleration and definition of virtual destructor of the base class, you could just write virtual ~Base() = default; on class decleration. However, in our case it's not like that.
As far as I know, MSVC allow you to write something like that on class decleration: virtual ~Base() = 0 {}. So you don't need to seperate decleration and definition with inline keyword. But it will only work with MSVC compiler.
Real world example:
BaseException.h:
#pragma once
#include <string>
class BaseException : public std::exception {
public:
BaseException(std::string message) noexcept : message(std::move(message)) {}
virtual char const* what() const noexcept { return message.c_str(); }
virtual ~BaseException() = 0;
private:
std::string message;
};
inline BaseException::~BaseException() = default;
SomeException.h:
#pragma once
#include "BaseException.h"
class SomeException : public BaseException {
public:
SomeException(std::string message) noexcept : BaseException(std::move(message)) {}
};
SomeOtherException.h:
#pragma once
#include "BaseException.h"
class SomeOtherException : public BaseException {
public:
SomeOtherException(std::string message) noexcept : BaseException(std::move(message)) {}
};
main.cpp:
#include <SomeException.h>
#include <SomeOtherException.h>
#include <iostream>
using namespace std;
static int DoSomething(int argc) {
try {
switch (argc) {
case 0:
throw SomeException("some");
case 1:
throw SomeOtherException("some other");
default:
return 0;
}
}
catch (const exception& ex) {
cout << ex.what() << endl;
return 1;
}
}
int main(int argc, char**) {
return DoSomething(argc);
}
Unless you are writing a library or have special reasons, you can forget about inline and use link-time optimization instead. It removes the requirement that a function definition must be in a header for it to be considered for inlining across compilation units, which is precisely what inline allows.
(But see Is there any reason why not to use link time optimization?)
C++ inline is totally different to C inline.
#include <iostream>
extern inline int i[];
int i [5];
struct c {
int function (){return 1;} // implicitly inline
static inline int j = 3; // explicitly inline
static int k; // without inline, a static member has to be defined out of line
static int f (){return 1;} // but a static method does not // implicitly inline
};
extern inline int b;
int b=3;
int c::k = 3; // when a static member is defined out of line it cannot have a static
// specifier and if it doesn't have an `inline` specifier in the
// declaration or on the definition then it is not inline and always
// emits a strong global symbol in the translation unit
int main() {
c j;
std::cout << i;
}
inline on its own affects the compiler, assembler and the linker. It is a directive to the compiler saying only emit a symbol for this function/data if it's used in the translation unit, and if it is, then like class methods, tell the assembler to store them in the section .section .text.c::function(),"axG",#progbits,c::function(),comdat or .section .bss.i,"awG",#nobits,i,comdat for unitialised data or .section .data.b,"awG",#progbits,b,comdat for initialised data. Template instantiations also go in their own comdat groups.
This follows .section name, "flags"MG, #type, entsize, GroupName[, linkage]. For instance, the section name is .text.c::function(). axG means the section is allocatable, executable and in a group i.e. a group name will be specified (and there is no M flag so no entsize will be specified); #progbits means the section contains data and isn't blank; c::function() is the group name and the group has comdat linkage meaning that in all object files, all sections encountered with this group name tagged with comdat will be removed from the final executable except for 1 i.e. the compiler makes sure that there is only one definition in the translation unit and then tells the assembler to put it in its own group in the object file (1 section in 1 group) and then the linker will make sure that if any object files have a group with the same name, then only include one in the final .exe. The difference between inline and not using inline is now visible to the assembler and as a result the linker, because it's not stored in the regular .data or .text etc by the assembler due to their directives. Only inline symbols with external linkage are given external comdat linkage like this -- static linkage (local) symbols do not need to go in comdat groups.
inline on a non-static method declaration in a class makes the method inline if it is defined out-of-line, this will prevent the method being emitted in the translation unit if it is not referenced in the translation unit. The same effect is achieved by putting inline on the out-of-line definition. When a method is defined out-of-line without an inline specifier and the declaration in the class is not inline then it will emit a symbol for the method in the translation unit at all times because it will have external linkage rather than external comdat linkage. If the method is defined in the class then it is implicitly inline, which gives it external comdat linkage rather than external linkage.
static inline on a member in a class (as opposed to method) makes it a static member (which does not refer to its linkage -- it has the linkage of its class which may be extern). static inline also allows static members of the class to be defined inside the class instead of needing to be declared in the class and then defined out-of-line (without static in the definition, which wasn't allowed without -fpermissive). *static inline* also makes the members inline and not static inline -- inline means that the definition is only emitted if it is referenced in the translation unit. Previously you had to specify inline on the out-of-line definition to make the member inline.
Seeing as static methods can be defined in the class, static inline has no effect on the static method defined in the class, which always has external linkage, is a static method and is inline. If it is defined out of line then inline must be used to make it inline (i.e. to give to external comdat linkage rather than just external linkage), and static still can't be used.
static inline at file scope only affects the compiler. It means to the compiler: only emit a symbol for this function/data if it's used in the translation unit and do so as a regular static symbol (store in.text /.data without .globl directive). To the assembler there is now no difference between static and static inline. Like the other forms of inline, it cannot be used on a class, which is a type, but can be used on an object of the type of that class. This form of static inline also cannot be used on members or methods of a function, where it will always be treated inline as the static means something else in a class (it means that the class is acting as a scope rather than it being a member of or method to be used on an object).
extern inline is a declaration that means you must define this symbol in the translation unit if it is referenced or throw compiler error; if it's defined then treat it as a regular inline and to the assembler and linker there will be no difference between extern inline and inline, so this is a compiler guard only.
extern inline int i[];
extern int i[]; //allowed repetition of declaration with incomplete type, inherits inline property
extern int i[5]; //declaration now has complete type
extern int i[5]; //allowed redeclaration if it is the same complete type or has not yet been completed
extern int i[6]; //error, redeclaration with different complete type
int i[5]; //definition, must have complete type and same complete type as the declaration if there is a declaration with a complete type
The whole of the above without the error line collapses to inline int i[5]. Obviously if you did extern inline int i[] = {5}; then extern would be ignored due to the explicit definition through assignment.
I think the reason that static is not allowed on a static out-of-line definition without -fpermissive is because it implies that the static refers to static linkage, because it's not immediately obvious to the programmer that it is a member of a class or whether that class has , where the static means something different. -fpermissive ignores the static specifier on the out-of-line definition and it means nothing. In the case of a simple integer, k can't be defined out of a namespace, if c were a namespace, but if k were a function, then there would be no way of visibly telling from the line of code whether it is an out of line definition of a function in a namespace with static linkage, or an out-of-line definition of a static member with external linkage, and may give the wrong impression to the programmer / reader of the code.
For local classes, inline on a member / method will result in a compiler error and members and methods have no linkage.
For inline on a namespace, see this and this
Inline keyword requests the compiler to replace the function call with the body of the function ,it first evaluates the expression and then passed.It reduces the function call overhead as there is no need to store the return address and stack memory is not required for function arguments.
When to use:
To Improve performance
To reduce call overhead .
As it's just a request to the compiler, certain functions won't be inlined
*large functions
functions having too many conditional arguments
recursive code and code with loops etc.
You want to put it in the very beginning, before return type. But most Compilers ignore it. If it's defined, and it has a smaller block of code, most compilers consider it inline anyway.
When developing and debugging code, leave inline out. It complicates debugging.
The major reason for adding them is to help optimize the generated code. Typically this trades increased code space for speed, but sometimes inline saves both code space and execution time.
Expending this kind of thought about performance optimization before algorithm completion is premature optimization.
When one should inline :
1.When one want to avoid overhead of things happening when function is called like parameter passing , control transfer, control return etc.
2.The function should be small,frequently called and making inline is really advantageous since as per 80-20 rule,try to make those function inline which has major impact on program performance.
As we know that inline is just a request to compiler similar to register and it will cost you at Object code size.

Do I need to use inline keywords? [duplicate]

When should I write the keyword inline for a function/method in C++?
After seeing some answers, some related questions:
When should I not write the keyword 'inline' for a function/method in C++?
When will the compiler not know when to make a function/method 'inline'?
Does it matter if an application is multithreaded when one writes 'inline' for a function/method?
Oh man, one of my pet peeves.
inline is more like static or extern than a directive telling the compiler to inline your functions. extern, static, inline are linkage directives, used almost exclusively by the linker, not the compiler.
It is said that inline hints to the compiler that you think the function should be inlined. That may have been true in 1998, but a decade later the compiler needs no such hints. Not to mention humans are usually wrong when it comes to optimizing code, so most compilers flat out ignore the 'hint'.
static - the variable/function name cannot be used in other translation units. Linker needs to make sure it doesn't accidentally use a statically defined variable/function from another translation unit.
extern - use this variable/function name in this translation unit but don't complain if it isn't defined. The linker will sort it out and make sure all the code that tried to use some extern symbol has its address.
inline - this function will be defined in multiple translation units, don't worry about it. The linker needs to make sure all translation units use a single instance of the variable/function.
Note: Generally, declaring templates inline is pointless, as they have the linkage semantics of inline already. However, explicit specialization and instantiation of templates require inline to be used.
Specific answers to your questions:
When should I write the keyword 'inline' for a function/method in C++?
Only when you want the function to be defined in a header. More exactly only when the function's definition can show up in multiple translation units. It's a good idea to define small (as in one liner) functions in the header file as it gives the compiler more information to work with while optimizing your code. It also increases compilation time.
When should I not write the keyword 'inline' for a function/method in C++?
Don't add inline just because you think your code will run faster if the compiler inlines it.
When will the compiler not know when to make a function/method 'inline'?
Generally, the compiler will be able to do this better than you. However, the compiler doesn't have the option to inline code if it doesn't have the function definition. In maximally optimized code usually all private methods are inlined whether you ask for it or not.
As an aside to prevent inlining in GCC, use __attribute__(( noinline )), and in Visual Studio, use __declspec(noinline).
Does it matter if an application is multithreaded when one writes 'inline' for a function/method?
Multithreading doesn't affect inlining in any way.
I'd like to contribute to all of the great answers in this thread with a convincing example to disperse any remaining misunderstanding.
Given two source files, such as:
inline111.cpp:
#include <iostream>
void bar();
inline int fun() {
return 111;
}
int main() {
std::cout << "inline111: fun() = " << fun() << ", &fun = " << (void*) &fun;
bar();
}
inline222.cpp:
#include <iostream>
inline int fun() {
return 222;
}
void bar() {
std::cout << "inline222: fun() = " << fun() << ", &fun = " << (void*) &fun;
}
Case A:
Compile:
g++ -std=c++11 inline111.cpp inline222.cpp
Output:
inline111: fun() = 111, &fun = 0x4029a0
inline222: fun() = 111, &fun = 0x4029a0
Discussion:
Even thou you ought to have identical definitions of your inline
functions, C++ compiler does not flag it if that is not the case (actually, due to separate compilation it has no ways to check it). It is your own duty to ensure this!
Linker does not complain about One Definition Rule, as fun() is declared as inline. However, because inline111.cpp is the first translation unit (which actually calls fun()) processed by compiler, the compiler instantiates fun() upon its first call-encounter in inline111.cpp. If compiler decides not to expand fun() upon its call from anywhere else in your program (e.g. from inline222.cpp), the call to fun() will always be linked to its instance produced from inline111.cpp (the call to fun() inside inline222.cpp may also produce an instance in that translation unit, but it will remain unlinked). Indeed, that is evident from the identical &fun = 0x4029a0 print-outs.
Finally, despite the inline suggestion to the compiler to actually expand the one-liner fun(), it ignores your suggestion completely, which is clear because fun() = 111 in both of the lines.
Case B:
Compile (notice reverse order):
g++ -std=c++11 inline222.cpp inline111.cpp
Output:
inline111: fun() = 222, &fun = 0x402980
inline222: fun() = 222, &fun = 0x402980
Discussion:
This case asserts what have been discussed in Case A.
Notice an important point, that if you comment out the actual call to fun() in inline222.cpp (e.g. comment out cout-statement in inline222.cpp completely) then, despite the compilation order of your translation units, fun() will be instantiated upon it's first call encounter in inline111.cpp, resulting in print-out for Case B as inline111: fun() = 111, &fun = 0x402980.
Case C:
Compile (notice -O2):
g++ -std=c++11 -O2 inline222.cpp inline111.cpp
or
g++ -std=c++11 -O2 inline111.cpp inline222.cpp
Output:
inline111: fun() = 111, &fun = 0x402900
inline222: fun() = 222, &fun = 0x402900
Discussion:
As is described here, -O2 optimization encourages compiler to actually expand the functions that can be inlined (Notice also that -fno-inline is default without optimization options). As is evident from the outprint here, the fun() has actually been inline expanded (according to its definition in that particular translation unit), resulting in two different fun() print-outs. Despite this, there is still only one globally linked instance of fun() (as required by the standard), as is evident from identical &fun print-out.
You still need to explicitly inline your function when doing template specialization (if specialization is in .h file)
1) Nowadays, pretty much never. If it's a good idea to inline a function, the compiler will do it without your help.
2) Always. See #1.
(Edited to reflect that you broke your question into two questions...)
When should I not write the keyword 'inline' for a function/method in C++?
If the function is declared in the header and defined in the .cpp file, you should not write the keyword.
When will the the compiler not know when to make a function/method 'inline'?
There is no such situation. The compiler cannot make a function inline. All it can do is to inline some or all calls to the function. It can't do so if it hasn't got the code of the function (in that case the linker needs to do it if it is able to do so).
Does it matter if an application is multithreaded when one writes 'inline' for a function/method?
No, that does not matter at all.
When will the the compiler not know when to make a function/method 'inline'?
This depends on the compiler used. Do not blindly trust that nowadays compilers know better then humans how to inline and you should never use it for performance reasons, because it's linkage directive rather than optimization hint. While I agree that ideologically are these arguments correct encountering reality might be a different thing.
After reading multiple threads around I tried out of curiosity the effects of inline on the code I'm just working and the results were that I got measurable speedup for GCC and no speed up for Intel compiler.
(More detail: math simulations with few critical functions defined outside class, GCC 4.6.3 (g++ -O3), ICC 13.1.0 (icpc -O3); adding inline to critical points caused +6% speedup with GCC code).
So if you qualify GCC 4.6 as a modern compiler the result is that inline directive still matters if you write CPU intensive tasks and know where exactly is the bottleneck.
In reality, pretty much never. All you're doing is suggesting that the compiler make a given function inline (e.g., replace all calls to this function /w its body). There are no guarantees, of course: the compiler may ignore the directive.
The compiler will generally do a good job of detecting + optimizing things like this.
gcc by default does not inline any functions when compiling without
optimization enabled. I don't know about visual studio – deft_code
I checked this for Visual Studio 9 (15.00.30729.01) by compiling with /FAcs and looking at the assembly code:
The compiler produced calls to member functions without optimization enabled in debug mode. Even if the function is marked with __forceinline, no inline runtime code is produced.
F.5: If a function is very small and time-critical, declare it inline
Reason: Some optimizers are good at inlining without hints from the programmer, but don’t rely on it. Measure! Over the last 40 years or so, we have been promised compilers that can inline better than humans without hints from humans. We are still waiting. Specifying inline (explicitly, or implicitly when writing member functions inside a class definition) encourages the compiler to do a better job.
Source: https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines.html#Rf-inline
For examples and exceptions, go to the Source (see above).
One use case might occur on inheritance. For example, if all below cases are true:
you have a base class of some class
the base class needs to be abstract
the base class has no pure virtual method other than destructor
you don't want to create cpp file for the base class because in vain
then you have to define the destructor; otherwise, you will have some undefined referance linker errors. Moreover, you have to do not only define but also to define the destructor with inline keyword; otherwise, you will have multiple definition linker errors.
This may happen for some helper classes that contains only static methods or writing base exception classes etc.
Let's give an example:
Base.h:
class Base {
public:
Base(SomeElementType someElement) noexcept : _someElement(std::move(someElement)) {}
virtual ~Base() = 0;
protected:
SomeElementType _someElement;
}
inline Base::~Base() = default;
Derived1.h:
#include "Base.h"
class Derived1 : public Base {
public:
Derived1(SomeElementType someElement) noexcept : Base(std::move(someElement)) {}
void DoSomething1() const;
}
Derived1.cpp:
#include "Derived1.h"
void Derived1::DoSomething1() const {
// use _someElement
}
Derived2.h:
#include "Base.h"
class Derived2 : public Base {
public:
Derived2(SomeElementType someElement) noexcept : Base(std::move(someElement)) {}
void DoSomething2() const;
}
Derived2.cpp:
#include "Derived2.h"
void Derived2::DoSomething2() const {
// use _someElement
}
Generally, abstract classes have some pure virtual methods other than constructor or destructor. So, you didn't have to seperate decleration and definition of virtual destructor of the base class, you could just write virtual ~Base() = default; on class decleration. However, in our case it's not like that.
As far as I know, MSVC allow you to write something like that on class decleration: virtual ~Base() = 0 {}. So you don't need to seperate decleration and definition with inline keyword. But it will only work with MSVC compiler.
Real world example:
BaseException.h:
#pragma once
#include <string>
class BaseException : public std::exception {
public:
BaseException(std::string message) noexcept : message(std::move(message)) {}
virtual char const* what() const noexcept { return message.c_str(); }
virtual ~BaseException() = 0;
private:
std::string message;
};
inline BaseException::~BaseException() = default;
SomeException.h:
#pragma once
#include "BaseException.h"
class SomeException : public BaseException {
public:
SomeException(std::string message) noexcept : BaseException(std::move(message)) {}
};
SomeOtherException.h:
#pragma once
#include "BaseException.h"
class SomeOtherException : public BaseException {
public:
SomeOtherException(std::string message) noexcept : BaseException(std::move(message)) {}
};
main.cpp:
#include <SomeException.h>
#include <SomeOtherException.h>
#include <iostream>
using namespace std;
static int DoSomething(int argc) {
try {
switch (argc) {
case 0:
throw SomeException("some");
case 1:
throw SomeOtherException("some other");
default:
return 0;
}
}
catch (const exception& ex) {
cout << ex.what() << endl;
return 1;
}
}
int main(int argc, char**) {
return DoSomething(argc);
}
Unless you are writing a library or have special reasons, you can forget about inline and use link-time optimization instead. It removes the requirement that a function definition must be in a header for it to be considered for inlining across compilation units, which is precisely what inline allows.
(But see Is there any reason why not to use link time optimization?)
C++ inline is totally different to C inline.
#include <iostream>
extern inline int i[];
int i [5];
struct c {
int function (){return 1;} // implicitly inline
static inline int j = 3; // explicitly inline
static int k; // without inline, a static member has to be defined out of line
static int f (){return 1;} // but a static method does not // implicitly inline
};
extern inline int b;
int b=3;
int c::k = 3; // when a static member is defined out of line it cannot have a static
// specifier and if it doesn't have an `inline` specifier in the
// declaration or on the definition then it is not inline and always
// emits a strong global symbol in the translation unit
int main() {
c j;
std::cout << i;
}
inline on its own affects the compiler, assembler and the linker. It is a directive to the compiler saying only emit a symbol for this function/data if it's used in the translation unit, and if it is, then like class methods, tell the assembler to store them in the section .section .text.c::function(),"axG",#progbits,c::function(),comdat or .section .bss.i,"awG",#nobits,i,comdat for unitialised data or .section .data.b,"awG",#progbits,b,comdat for initialised data. Template instantiations also go in their own comdat groups.
This follows .section name, "flags"MG, #type, entsize, GroupName[, linkage]. For instance, the section name is .text.c::function(). axG means the section is allocatable, executable and in a group i.e. a group name will be specified (and there is no M flag so no entsize will be specified); #progbits means the section contains data and isn't blank; c::function() is the group name and the group has comdat linkage meaning that in all object files, all sections encountered with this group name tagged with comdat will be removed from the final executable except for 1 i.e. the compiler makes sure that there is only one definition in the translation unit and then tells the assembler to put it in its own group in the object file (1 section in 1 group) and then the linker will make sure that if any object files have a group with the same name, then only include one in the final .exe. The difference between inline and not using inline is now visible to the assembler and as a result the linker, because it's not stored in the regular .data or .text etc by the assembler due to their directives. Only inline symbols with external linkage are given external comdat linkage like this -- static linkage (local) symbols do not need to go in comdat groups.
inline on a non-static method declaration in a class makes the method inline if it is defined out-of-line, this will prevent the method being emitted in the translation unit if it is not referenced in the translation unit. The same effect is achieved by putting inline on the out-of-line definition. When a method is defined out-of-line without an inline specifier and the declaration in the class is not inline then it will emit a symbol for the method in the translation unit at all times because it will have external linkage rather than external comdat linkage. If the method is defined in the class then it is implicitly inline, which gives it external comdat linkage rather than external linkage.
static inline on a member in a class (as opposed to method) makes it a static member (which does not refer to its linkage -- it has the linkage of its class which may be extern). static inline also allows static members of the class to be defined inside the class instead of needing to be declared in the class and then defined out-of-line (without static in the definition, which wasn't allowed without -fpermissive). *static inline* also makes the members inline and not static inline -- inline means that the definition is only emitted if it is referenced in the translation unit. Previously you had to specify inline on the out-of-line definition to make the member inline.
Seeing as static methods can be defined in the class, static inline has no effect on the static method defined in the class, which always has external linkage, is a static method and is inline. If it is defined out of line then inline must be used to make it inline (i.e. to give to external comdat linkage rather than just external linkage), and static still can't be used.
static inline at file scope only affects the compiler. It means to the compiler: only emit a symbol for this function/data if it's used in the translation unit and do so as a regular static symbol (store in.text /.data without .globl directive). To the assembler there is now no difference between static and static inline. Like the other forms of inline, it cannot be used on a class, which is a type, but can be used on an object of the type of that class. This form of static inline also cannot be used on members or methods of a function, where it will always be treated inline as the static means something else in a class (it means that the class is acting as a scope rather than it being a member of or method to be used on an object).
extern inline is a declaration that means you must define this symbol in the translation unit if it is referenced or throw compiler error; if it's defined then treat it as a regular inline and to the assembler and linker there will be no difference between extern inline and inline, so this is a compiler guard only.
extern inline int i[];
extern int i[]; //allowed repetition of declaration with incomplete type, inherits inline property
extern int i[5]; //declaration now has complete type
extern int i[5]; //allowed redeclaration if it is the same complete type or has not yet been completed
extern int i[6]; //error, redeclaration with different complete type
int i[5]; //definition, must have complete type and same complete type as the declaration if there is a declaration with a complete type
The whole of the above without the error line collapses to inline int i[5]. Obviously if you did extern inline int i[] = {5}; then extern would be ignored due to the explicit definition through assignment.
I think the reason that static is not allowed on a static out-of-line definition without -fpermissive is because it implies that the static refers to static linkage, because it's not immediately obvious to the programmer that it is a member of a class or whether that class has , where the static means something different. -fpermissive ignores the static specifier on the out-of-line definition and it means nothing. In the case of a simple integer, k can't be defined out of a namespace, if c were a namespace, but if k were a function, then there would be no way of visibly telling from the line of code whether it is an out of line definition of a function in a namespace with static linkage, or an out-of-line definition of a static member with external linkage, and may give the wrong impression to the programmer / reader of the code.
For local classes, inline on a member / method will result in a compiler error and members and methods have no linkage.
For inline on a namespace, see this and this
Inline keyword requests the compiler to replace the function call with the body of the function ,it first evaluates the expression and then passed.It reduces the function call overhead as there is no need to store the return address and stack memory is not required for function arguments.
When to use:
To Improve performance
To reduce call overhead .
As it's just a request to the compiler, certain functions won't be inlined
*large functions
functions having too many conditional arguments
recursive code and code with loops etc.
You want to put it in the very beginning, before return type. But most Compilers ignore it. If it's defined, and it has a smaller block of code, most compilers consider it inline anyway.
When developing and debugging code, leave inline out. It complicates debugging.
The major reason for adding them is to help optimize the generated code. Typically this trades increased code space for speed, but sometimes inline saves both code space and execution time.
Expending this kind of thought about performance optimization before algorithm completion is premature optimization.
When one should inline :
1.When one want to avoid overhead of things happening when function is called like parameter passing , control transfer, control return etc.
2.The function should be small,frequently called and making inline is really advantageous since as per 80-20 rule,try to make those function inline which has major impact on program performance.
As we know that inline is just a request to compiler similar to register and it will cost you at Object code size.

not-inline function definition in header file which is included by two inline functions [duplicate]

When should I write the keyword inline for a function/method in C++?
After seeing some answers, some related questions:
When should I not write the keyword 'inline' for a function/method in C++?
When will the compiler not know when to make a function/method 'inline'?
Does it matter if an application is multithreaded when one writes 'inline' for a function/method?
Oh man, one of my pet peeves.
inline is more like static or extern than a directive telling the compiler to inline your functions. extern, static, inline are linkage directives, used almost exclusively by the linker, not the compiler.
It is said that inline hints to the compiler that you think the function should be inlined. That may have been true in 1998, but a decade later the compiler needs no such hints. Not to mention humans are usually wrong when it comes to optimizing code, so most compilers flat out ignore the 'hint'.
static - the variable/function name cannot be used in other translation units. Linker needs to make sure it doesn't accidentally use a statically defined variable/function from another translation unit.
extern - use this variable/function name in this translation unit but don't complain if it isn't defined. The linker will sort it out and make sure all the code that tried to use some extern symbol has its address.
inline - this function will be defined in multiple translation units, don't worry about it. The linker needs to make sure all translation units use a single instance of the variable/function.
Note: Generally, declaring templates inline is pointless, as they have the linkage semantics of inline already. However, explicit specialization and instantiation of templates require inline to be used.
Specific answers to your questions:
When should I write the keyword 'inline' for a function/method in C++?
Only when you want the function to be defined in a header. More exactly only when the function's definition can show up in multiple translation units. It's a good idea to define small (as in one liner) functions in the header file as it gives the compiler more information to work with while optimizing your code. It also increases compilation time.
When should I not write the keyword 'inline' for a function/method in C++?
Don't add inline just because you think your code will run faster if the compiler inlines it.
When will the compiler not know when to make a function/method 'inline'?
Generally, the compiler will be able to do this better than you. However, the compiler doesn't have the option to inline code if it doesn't have the function definition. In maximally optimized code usually all private methods are inlined whether you ask for it or not.
As an aside to prevent inlining in GCC, use __attribute__(( noinline )), and in Visual Studio, use __declspec(noinline).
Does it matter if an application is multithreaded when one writes 'inline' for a function/method?
Multithreading doesn't affect inlining in any way.
I'd like to contribute to all of the great answers in this thread with a convincing example to disperse any remaining misunderstanding.
Given two source files, such as:
inline111.cpp:
#include <iostream>
void bar();
inline int fun() {
return 111;
}
int main() {
std::cout << "inline111: fun() = " << fun() << ", &fun = " << (void*) &fun;
bar();
}
inline222.cpp:
#include <iostream>
inline int fun() {
return 222;
}
void bar() {
std::cout << "inline222: fun() = " << fun() << ", &fun = " << (void*) &fun;
}
Case A:
Compile:
g++ -std=c++11 inline111.cpp inline222.cpp
Output:
inline111: fun() = 111, &fun = 0x4029a0
inline222: fun() = 111, &fun = 0x4029a0
Discussion:
Even thou you ought to have identical definitions of your inline
functions, C++ compiler does not flag it if that is not the case (actually, due to separate compilation it has no ways to check it). It is your own duty to ensure this!
Linker does not complain about One Definition Rule, as fun() is declared as inline. However, because inline111.cpp is the first translation unit (which actually calls fun()) processed by compiler, the compiler instantiates fun() upon its first call-encounter in inline111.cpp. If compiler decides not to expand fun() upon its call from anywhere else in your program (e.g. from inline222.cpp), the call to fun() will always be linked to its instance produced from inline111.cpp (the call to fun() inside inline222.cpp may also produce an instance in that translation unit, but it will remain unlinked). Indeed, that is evident from the identical &fun = 0x4029a0 print-outs.
Finally, despite the inline suggestion to the compiler to actually expand the one-liner fun(), it ignores your suggestion completely, which is clear because fun() = 111 in both of the lines.
Case B:
Compile (notice reverse order):
g++ -std=c++11 inline222.cpp inline111.cpp
Output:
inline111: fun() = 222, &fun = 0x402980
inline222: fun() = 222, &fun = 0x402980
Discussion:
This case asserts what have been discussed in Case A.
Notice an important point, that if you comment out the actual call to fun() in inline222.cpp (e.g. comment out cout-statement in inline222.cpp completely) then, despite the compilation order of your translation units, fun() will be instantiated upon it's first call encounter in inline111.cpp, resulting in print-out for Case B as inline111: fun() = 111, &fun = 0x402980.
Case C:
Compile (notice -O2):
g++ -std=c++11 -O2 inline222.cpp inline111.cpp
or
g++ -std=c++11 -O2 inline111.cpp inline222.cpp
Output:
inline111: fun() = 111, &fun = 0x402900
inline222: fun() = 222, &fun = 0x402900
Discussion:
As is described here, -O2 optimization encourages compiler to actually expand the functions that can be inlined (Notice also that -fno-inline is default without optimization options). As is evident from the outprint here, the fun() has actually been inline expanded (according to its definition in that particular translation unit), resulting in two different fun() print-outs. Despite this, there is still only one globally linked instance of fun() (as required by the standard), as is evident from identical &fun print-out.
You still need to explicitly inline your function when doing template specialization (if specialization is in .h file)
1) Nowadays, pretty much never. If it's a good idea to inline a function, the compiler will do it without your help.
2) Always. See #1.
(Edited to reflect that you broke your question into two questions...)
When should I not write the keyword 'inline' for a function/method in C++?
If the function is declared in the header and defined in the .cpp file, you should not write the keyword.
When will the the compiler not know when to make a function/method 'inline'?
There is no such situation. The compiler cannot make a function inline. All it can do is to inline some or all calls to the function. It can't do so if it hasn't got the code of the function (in that case the linker needs to do it if it is able to do so).
Does it matter if an application is multithreaded when one writes 'inline' for a function/method?
No, that does not matter at all.
When will the the compiler not know when to make a function/method 'inline'?
This depends on the compiler used. Do not blindly trust that nowadays compilers know better then humans how to inline and you should never use it for performance reasons, because it's linkage directive rather than optimization hint. While I agree that ideologically are these arguments correct encountering reality might be a different thing.
After reading multiple threads around I tried out of curiosity the effects of inline on the code I'm just working and the results were that I got measurable speedup for GCC and no speed up for Intel compiler.
(More detail: math simulations with few critical functions defined outside class, GCC 4.6.3 (g++ -O3), ICC 13.1.0 (icpc -O3); adding inline to critical points caused +6% speedup with GCC code).
So if you qualify GCC 4.6 as a modern compiler the result is that inline directive still matters if you write CPU intensive tasks and know where exactly is the bottleneck.
In reality, pretty much never. All you're doing is suggesting that the compiler make a given function inline (e.g., replace all calls to this function /w its body). There are no guarantees, of course: the compiler may ignore the directive.
The compiler will generally do a good job of detecting + optimizing things like this.
gcc by default does not inline any functions when compiling without
optimization enabled. I don't know about visual studio – deft_code
I checked this for Visual Studio 9 (15.00.30729.01) by compiling with /FAcs and looking at the assembly code:
The compiler produced calls to member functions without optimization enabled in debug mode. Even if the function is marked with __forceinline, no inline runtime code is produced.
F.5: If a function is very small and time-critical, declare it inline
Reason: Some optimizers are good at inlining without hints from the programmer, but don’t rely on it. Measure! Over the last 40 years or so, we have been promised compilers that can inline better than humans without hints from humans. We are still waiting. Specifying inline (explicitly, or implicitly when writing member functions inside a class definition) encourages the compiler to do a better job.
Source: https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines.html#Rf-inline
For examples and exceptions, go to the Source (see above).
One use case might occur on inheritance. For example, if all below cases are true:
you have a base class of some class
the base class needs to be abstract
the base class has no pure virtual method other than destructor
you don't want to create cpp file for the base class because in vain
then you have to define the destructor; otherwise, you will have some undefined referance linker errors. Moreover, you have to do not only define but also to define the destructor with inline keyword; otherwise, you will have multiple definition linker errors.
This may happen for some helper classes that contains only static methods or writing base exception classes etc.
Let's give an example:
Base.h:
class Base {
public:
Base(SomeElementType someElement) noexcept : _someElement(std::move(someElement)) {}
virtual ~Base() = 0;
protected:
SomeElementType _someElement;
}
inline Base::~Base() = default;
Derived1.h:
#include "Base.h"
class Derived1 : public Base {
public:
Derived1(SomeElementType someElement) noexcept : Base(std::move(someElement)) {}
void DoSomething1() const;
}
Derived1.cpp:
#include "Derived1.h"
void Derived1::DoSomething1() const {
// use _someElement
}
Derived2.h:
#include "Base.h"
class Derived2 : public Base {
public:
Derived2(SomeElementType someElement) noexcept : Base(std::move(someElement)) {}
void DoSomething2() const;
}
Derived2.cpp:
#include "Derived2.h"
void Derived2::DoSomething2() const {
// use _someElement
}
Generally, abstract classes have some pure virtual methods other than constructor or destructor. So, you didn't have to seperate decleration and definition of virtual destructor of the base class, you could just write virtual ~Base() = default; on class decleration. However, in our case it's not like that.
As far as I know, MSVC allow you to write something like that on class decleration: virtual ~Base() = 0 {}. So you don't need to seperate decleration and definition with inline keyword. But it will only work with MSVC compiler.
Real world example:
BaseException.h:
#pragma once
#include <string>
class BaseException : public std::exception {
public:
BaseException(std::string message) noexcept : message(std::move(message)) {}
virtual char const* what() const noexcept { return message.c_str(); }
virtual ~BaseException() = 0;
private:
std::string message;
};
inline BaseException::~BaseException() = default;
SomeException.h:
#pragma once
#include "BaseException.h"
class SomeException : public BaseException {
public:
SomeException(std::string message) noexcept : BaseException(std::move(message)) {}
};
SomeOtherException.h:
#pragma once
#include "BaseException.h"
class SomeOtherException : public BaseException {
public:
SomeOtherException(std::string message) noexcept : BaseException(std::move(message)) {}
};
main.cpp:
#include <SomeException.h>
#include <SomeOtherException.h>
#include <iostream>
using namespace std;
static int DoSomething(int argc) {
try {
switch (argc) {
case 0:
throw SomeException("some");
case 1:
throw SomeOtherException("some other");
default:
return 0;
}
}
catch (const exception& ex) {
cout << ex.what() << endl;
return 1;
}
}
int main(int argc, char**) {
return DoSomething(argc);
}
Unless you are writing a library or have special reasons, you can forget about inline and use link-time optimization instead. It removes the requirement that a function definition must be in a header for it to be considered for inlining across compilation units, which is precisely what inline allows.
(But see Is there any reason why not to use link time optimization?)
C++ inline is totally different to C inline.
#include <iostream>
extern inline int i[];
int i [5];
struct c {
int function (){return 1;} // implicitly inline
static inline int j = 3; // explicitly inline
static int k; // without inline, a static member has to be defined out of line
static int f (){return 1;} // but a static method does not // implicitly inline
};
extern inline int b;
int b=3;
int c::k = 3; // when a static member is defined out of line it cannot have a static
// specifier and if it doesn't have an `inline` specifier in the
// declaration or on the definition then it is not inline and always
// emits a strong global symbol in the translation unit
int main() {
c j;
std::cout << i;
}
inline on its own affects the compiler, assembler and the linker. It is a directive to the compiler saying only emit a symbol for this function/data if it's used in the translation unit, and if it is, then like class methods, tell the assembler to store them in the section .section .text.c::function(),"axG",#progbits,c::function(),comdat or .section .bss.i,"awG",#nobits,i,comdat for unitialised data or .section .data.b,"awG",#progbits,b,comdat for initialised data. Template instantiations also go in their own comdat groups.
This follows .section name, "flags"MG, #type, entsize, GroupName[, linkage]. For instance, the section name is .text.c::function(). axG means the section is allocatable, executable and in a group i.e. a group name will be specified (and there is no M flag so no entsize will be specified); #progbits means the section contains data and isn't blank; c::function() is the group name and the group has comdat linkage meaning that in all object files, all sections encountered with this group name tagged with comdat will be removed from the final executable except for 1 i.e. the compiler makes sure that there is only one definition in the translation unit and then tells the assembler to put it in its own group in the object file (1 section in 1 group) and then the linker will make sure that if any object files have a group with the same name, then only include one in the final .exe. The difference between inline and not using inline is now visible to the assembler and as a result the linker, because it's not stored in the regular .data or .text etc by the assembler due to their directives. Only inline symbols with external linkage are given external comdat linkage like this -- static linkage (local) symbols do not need to go in comdat groups.
inline on a non-static method declaration in a class makes the method inline if it is defined out-of-line, this will prevent the method being emitted in the translation unit if it is not referenced in the translation unit. The same effect is achieved by putting inline on the out-of-line definition. When a method is defined out-of-line without an inline specifier and the declaration in the class is not inline then it will emit a symbol for the method in the translation unit at all times because it will have external linkage rather than external comdat linkage. If the method is defined in the class then it is implicitly inline, which gives it external comdat linkage rather than external linkage.
static inline on a member in a class (as opposed to method) makes it a static member (which does not refer to its linkage -- it has the linkage of its class which may be extern). static inline also allows static members of the class to be defined inside the class instead of needing to be declared in the class and then defined out-of-line (without static in the definition, which wasn't allowed without -fpermissive). *static inline* also makes the members inline and not static inline -- inline means that the definition is only emitted if it is referenced in the translation unit. Previously you had to specify inline on the out-of-line definition to make the member inline.
Seeing as static methods can be defined in the class, static inline has no effect on the static method defined in the class, which always has external linkage, is a static method and is inline. If it is defined out of line then inline must be used to make it inline (i.e. to give to external comdat linkage rather than just external linkage), and static still can't be used.
static inline at file scope only affects the compiler. It means to the compiler: only emit a symbol for this function/data if it's used in the translation unit and do so as a regular static symbol (store in.text /.data without .globl directive). To the assembler there is now no difference between static and static inline. Like the other forms of inline, it cannot be used on a class, which is a type, but can be used on an object of the type of that class. This form of static inline also cannot be used on members or methods of a function, where it will always be treated inline as the static means something else in a class (it means that the class is acting as a scope rather than it being a member of or method to be used on an object).
extern inline is a declaration that means you must define this symbol in the translation unit if it is referenced or throw compiler error; if it's defined then treat it as a regular inline and to the assembler and linker there will be no difference between extern inline and inline, so this is a compiler guard only.
extern inline int i[];
extern int i[]; //allowed repetition of declaration with incomplete type, inherits inline property
extern int i[5]; //declaration now has complete type
extern int i[5]; //allowed redeclaration if it is the same complete type or has not yet been completed
extern int i[6]; //error, redeclaration with different complete type
int i[5]; //definition, must have complete type and same complete type as the declaration if there is a declaration with a complete type
The whole of the above without the error line collapses to inline int i[5]. Obviously if you did extern inline int i[] = {5}; then extern would be ignored due to the explicit definition through assignment.
I think the reason that static is not allowed on a static out-of-line definition without -fpermissive is because it implies that the static refers to static linkage, because it's not immediately obvious to the programmer that it is a member of a class or whether that class has , where the static means something different. -fpermissive ignores the static specifier on the out-of-line definition and it means nothing. In the case of a simple integer, k can't be defined out of a namespace, if c were a namespace, but if k were a function, then there would be no way of visibly telling from the line of code whether it is an out of line definition of a function in a namespace with static linkage, or an out-of-line definition of a static member with external linkage, and may give the wrong impression to the programmer / reader of the code.
For local classes, inline on a member / method will result in a compiler error and members and methods have no linkage.
For inline on a namespace, see this and this
Inline keyword requests the compiler to replace the function call with the body of the function ,it first evaluates the expression and then passed.It reduces the function call overhead as there is no need to store the return address and stack memory is not required for function arguments.
When to use:
To Improve performance
To reduce call overhead .
As it's just a request to the compiler, certain functions won't be inlined
*large functions
functions having too many conditional arguments
recursive code and code with loops etc.
You want to put it in the very beginning, before return type. But most Compilers ignore it. If it's defined, and it has a smaller block of code, most compilers consider it inline anyway.
When developing and debugging code, leave inline out. It complicates debugging.
The major reason for adding them is to help optimize the generated code. Typically this trades increased code space for speed, but sometimes inline saves both code space and execution time.
Expending this kind of thought about performance optimization before algorithm completion is premature optimization.
When one should inline :
1.When one want to avoid overhead of things happening when function is called like parameter passing , control transfer, control return etc.
2.The function should be small,frequently called and making inline is really advantageous since as per 80-20 rule,try to make those function inline which has major impact on program performance.
As we know that inline is just a request to compiler similar to register and it will cost you at Object code size.