I have seen in stackoverflow that
//define in .h
inline void fun()
{
static int i; // one instance include in multiple cpp
}
static inline void fun1()
{
static int i; // multiple instance included in multiple cpp
}
I often write signleton in such a pattern
//define in .h
class Singleton
{
static Singleton& Instance()
{
static Singleton s;
return s;
}
private:
int i;
}
a lot of coders write in this way, Can someone explain is it correct, how C++ ensure one instance?
actually in the inline and static inline version, there is no clear cpp declaration to ensure single instance.
The C++ standard does not "ensure" anything.
The C++ standard specifies the observed results, what happens as the result of this declaration
It is up to each C++ compiler to implement this C++ specification in the manner that produces the specified results.
The C++ standard does not specify exactly how the compiler and the linker go about doing this. The low level details that produces these results are not specified or mandated by the C++ standard, in any way. This is entirely up to the compiler and the linker.
Having said that: the common approach is for the compiler to produce an instance of the static object in every compiled .cpp file. It is also tagged in some manner that uniquely identifies it; and indicates that, when linked with other translation units, only one instance of the uniquely-identified object (in all the compiled object files) is produced in the final linked executable.
This is a problem that was inherited from C and you have to go back quite a bit in history. So a long time a ago in a language not quite C++ ...
The inline keyword was just a hint to the compiler that you would like that function to get inlined. Now some compilers just ignored it because nothing said you had to inline functions marked inline. Some compilers addded a fudge factor to their automatic inline heuristic to make it more likely to get inlined. Others always inlined.
This then caused a problems for functions defined in headers because when the function was not actually inlined you ended up with the same function in multiple compilation units and then the linker complained.
Some compilers marked inline functions so that the linker would ignore duplicate definitions. But to be portable you had to mark your functions static inline. That way, even if the function is present in each compilation unit, the function isn't exported and doesn't collide with definitions of the same function in other compilation units. Drawback is that you get multiple copies of the same function, which is a problem when you have local static variables or use the address of the function.
Warp forward to the near present...
Compilers have gotten a lot smarter about inlining automatically and the feature to mark inline function to allow multiple defintions has kind of taken hold and that is the meaning of the inline specifier in C++. Since C++17 this also holds for inline variables, not just functions.
So inline causes the compiler to mark the function (or variable) in the object file for the linker to
Allow multiple definitions without error or warning.
Pick any one of the definitions and replace all the other instances with that one.
All duplicates of the inline function will end up with the same address and any local static variable will end up with a single instance too. All copies become the same object.
PS: using a static local variable for a singleton is imho the best way as it avoids the Static Initialization Order Fiasco as much as can be and is thread safe.
Related
So I realize that when including a ".h" file, the compiler essentially copies the contents of that file to the point it was included. So obviously if I had "Utils.h" included in many files, if utils.h holds a functions implementation, it would cause the redefinition error.
I also realize using the inline keyword fixes this problem by essentially eliminating the function and in-lining it at its usage sites.
Now my question is, when the static keyword is used in the header file, it also seems to fix the problem, but I'm not sure I quite understand why/how it fixes the problem...? It's my understanding that static in a cpp file would essentially make it only available in that compilation unit.
To make sure we're all on the same page here is a snippet of the code in question:
//Utils.h (included in many places)
namespace utils {
void someUtil() {
//do work
}
}
where the above would throw the error, but with static and/or inline keyword, there would be no issue.
So I'm wanting to know what static is doing in this case, and should I use that as well as inline if its a small function body or...?
static, tells the compiler to generate the function in every translation unit where it is defined, and just not share it. So you end up with an arbitrary number of technically separate functions existing in the resulting executable if you use in many translation units and if you check the address of the function in different TUs you will have different results.
inline function on the other hand:
There may be more than one definition of an inline function or
variable (since C++17) in the program as long as each definition
appears in a different translation unit and (for non-static inline
functions and variables (since C++17)) all definitions are identical.
For example, an inline function or an inline variable (since C++17)
may be defined in a header file that is #include'd in multiple source
files.
So The compiler will then either inline calls to the function, or merge together the function definitions from different TU's (so that the resulting function exists once in the executable).
so in your case inline is what you need.
The way I think of inline in C++ is for linkage/scoping. I put it in the same basket with extern and static for global objects.
Typically for a function implemented in a header file, my go-to solution would be to make it static:
// In Foo.h
static void foo()
{
// Do stuff...
}
However, I believe this is also valid and does not seem to violate ODR:
// In Foo.h
inline void foo()
{
// Do stuff...
}
What are the semantic differences between the two? Also I'm not exactly sure what areas of the C++ standard would explain exact differences, or if it's just undefined and differences lie with the implementation.
inline conveys exactly what you want: "please suppress the ODR (One Definition Rule) for this function, so that each translation unit can (and must) supply its own copy of the function's definition".
The compiler will then either inline calls to the function, or merge together the function definitions from different TU's (so that the resulting function exists once in the executable).
static, on the other hand, tells the compiler to generate the function in every translation unit where it is defined, and just not share it. So you end up with an arbitrary number of technically separate functions existing in the resulting executable.
In a nutshell, if you use static, then taking the address of the function in different translation units will return different addresses (because you're telling the compiler to generate a function in each TU), but if you use inline, they'll show the same address (because you're defining one function, and just telling the compiler to merge the many definitions together).
The main difference is what happens with any static locals in the function -- if the function is static then each compilation unit will have its own copy of the static locals distinct from any other compilation unit. If the function is inline, there will only be one (set of) static local(s) shared by all compilation units.
In many cases you will not notice a difference because compilers and linkers are pretty smart these days.
However, an inline function must behave as-if it was a regular function.
A static function in a header will get compiled into every source file which includes it - so there will be lots of copies of it.
Mostly, this doesn't matter much, but there are a few ways it does.
An inline function has one address.
Static functions will have a different address in each translation unit.
Static-local variables: WIth the inline, there will be a single copy of them.
With static-functions, there will be a unique copy of each static-local variable for each translation unit that includes that function.
Thinking about this question from the original intents of keywords inline and static may be more helpful and clear.
inline functions
The original intent of keyword inline is to improve runtime performance, not for linkage/scoping as you said at the beginning. It is a hint that makes compiler attempt to generate code inline at the calling point rather than laying down the code once and calling it every time, which can avoid some overheads such as creating stack frame for the calls. In order to generate code inline, the function definition must be in scope, not just the declaration like ordinary functions. So, you should put the whole function definition in a header file foo.h, and #include "foo.h" when call it. These inline functions in different translation units must be identical token-by-token to obey ODR(One Definition Rule). And these all inline functions are just one single function, and so do static variables in this inline function.
static functions
Keyword static can be used to make functions local to a translation unit, namely that it gives them internal linkage. So if you put the whole function definition of foo() into a header file foo.h and mark it as static, all translation units which #include "foo.h" will have a local function foo(). In other words, the functions foo() in different translation units are not one single function, and neither do the static variables in these static functions.
static inline functions
So you can guess functioins marked by both static and inline. These are not the same functions in different translation units like static functions, but can give performance improvement by generate code inline.
No one seems to be mentioning that in C++, a static function is one that is called directly, not on an instance of the class. In other words, there is no implicit "this" pointer. If function foo of class MyClass is static, you say:
MyClass::foo(); // calls it
and not:
MyClass an_object = new MyClass();
an_object->foo();
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Inline functions in C++
What does the compiler do if I completely implement a class in its header file? A typical example follows:
class MyException
{
public:
explicit MyException(const char* file, int line) file(file), line(line) {};
const char* getFile() const { return file };
int getLine() const { return line };
private:
const char* const file;
const int line;
};
My intention is to use the class like this: throw MyException(__FILE__, __LINE__).
I include this header file into each .cpp file. I suppose the compiler will compile the class as many times as it is defined and include the (identical) machine code into every object file it produces. Now, what will the linker do? I tried a simpler example (without all those pesky const's) and it compiled fine.
What would happen, if instead of a simple class, I implemented a three-screenful-long C function in a header file? And the final question, should I split my example into .h and .cpp files?
All methods will be inline methods. You may loose some minimal time on the overall compilation, but it's ok. As far as I know the only problem that can occur is if you have a static non-cost member variable. Then you have to assign a storage place for it (place a definition and and initial value if you want) presumably in a .cpp or else you will get linker errors about multiple definition.
I've seen header-only projects which had only the main() function in a CPP, but that was heavily templated.
Update for C++17: You can declare static non-const members as inline in your header file since C++17. This makes header-only libraries easily possible without gymnastics like static variables inside inline functions.
A class definition itself doesn't produce any code. It just shows users of the class how it is layed out, so they can generate appropriate code to manipulate it.
It's the member functions of the class that generate code. When you define a member function inside the class definition it gives the function an implicit inline declaration.
A function call can be compiled and linked in one of two ways:
(1) A single copy of the function code with a RETURN assembly instruction at the end can be placed in the image, and a CALL assembly instruction can be placed (along with param passing and return value transfer) at the call site to transfer control to this code.
or
(2) An entire copy of the function implementation can replace the entire function call at the call site.
A function declared inline is a recommendation to the compiler to do it the second way. Further an inline declaration allows the function to be defined in several translation units (so it can be placed in a shared header file). In order for the compiler have the option of implementing the second method, it needs a copy of the function implementation at compile-time. This isn't available if the function implementation is in a foreign translation unit.
It should also be noted that modern compilers do complicated things with functions declared inline. See:
http://gcc.gnu.org/onlinedocs/gcc/Inline.html
When you implement member functions inside a header file, all those functions become implicitly inline.
What does this mean and what implications does it have?
As per,
C++03 Standard §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.
So Yes, every translation unit will have the definition of the inline function.This may result in increase in the size of your binaries.
Usually any good mainstream compiler will substitute function body at the point of call if needed, so marking functions inline merely for #1 is not really a good idea but if you want to make your intent clear to users of your class then you can do so by defining the functions within the header or explicitly marking your functions as inline.
Should I split my example into .h and .cpp files?
Yes, that is the usual compilation model that most of the projects use, wherein you separate the interface(.h) from the implementation(.cpp).The interfaces are shared with the users of your code as header files while the implementation is provided in the form of binaries.To some extent this provides a safeguard to your intellectual property.
This is known as the Separation Model.
C++ projects using templates will usually use the Inclusion Model rather than the Separation Model of usual C++ projects.
Is there any difference between inline member function (function body inline) and other normal member function (function body in a separate .cpp file)?
for example,
class A
{
void member(){}
};
and
// Header file (.hpp)
class B
{
void member();
};
// Implementation file (.cpp)
void B::member(){}
There is absolutely no difference.
The only difference between the two is that the member inside the class is implicitly tagged as inline. But this has no real meaning.
See: inline and good practices
The documentation says that the inline tag is a hint to the compiler (by the developer) that a method should be inlined. All modern compilers ignore this hint and use there own internal heuristic to determine when a method should be inlined (As humans are notoriously bad and making this decision).
The other use of inline is that it tells the linker that it may expect to see multiple definitions of a method. When the function definition is in the header file each compilation unit that gets the header file will have a definition of the function (assuming it is not inlined). Normally this would cause the linker to generate errors. With the inline tag the compiler understands why there are multiple definitions and will remove all but one from the application.
Note on inlining the processes: A method does not need to be in the header file to inlined. Modern compilers have a processes a full application optimization where all functions can be considered for inlining even if they have been compiled in different compilation units. Since the inline flag is generally ignored it make no difference if you put the method in the header or the source file.
Ignore the word inline here and compiler hints because it is not relevant.
The big practical difference in A and B is when they are used in different libraries.
With the case of A you can #include the header and are not required to link against anything. So you can use this class from different applications / libraries without any special linkage.
With the case of B, you need B.cpp and this should be compiled only into one library / application. Any other library or application that needs to use this class will need to link against the one that contains the actual body of the code.
With some setups / implementations you will need to specifically mark the class as "exported" or "imported" between libraries (for example with Windows you can use dllimport / dllexport and with GNU you can use attribute(visibility="default") )
The first one is implicitly inline, i.e. suggesting the compiler to expand it at the call site.
Other than the inline thing, there's a difference in that you could put more definitions in between the definition of class B, and the definition of the function.
For example, B.cpp might include header files that B.hpp doesn't, which can make a significant difference to the build process for large projects.
But even without a separate translation unit, you can occasionally have a circular dependency that's resolved by separating the definitions. For example the function might take a parameter of a type that's forward-declared before B is defined, then defined by the time the function is defined. If that type uses the definition of B in its own definition, it can't just be be defined before B.
I had a discussion with Johannes Schaub regarding the keyword inline.
The code there was this:
namespace ... {
static void someFunction() {
MYCLASS::GetInstance()->someFunction();
}
};
He stated that:
Putting this as an inline function may
save code size in the executable
But according to my findings here and here it wouldn't be needed, since:
[Inline] only occurs if the compiler's cost/benefit analysis show it to be profitable
Mainstream C++ compilers like Microsoft Visual C++ and GCC support an option that lets the compilers automatically inline any suitable function, even those not marked as inline functions.
Johannes however states that there are other benefits of explicitly specifying it. Unfortunately I do not understand them. For instance, he stated that And "inline" allows you to define the function multiple times in the program., which I am having a hard time understanding (and finding references to).
So
Is inline just a recommendation for the compiler?
Should it be explicitly stated when you have a small function (I guess 1-4 instructions?)
What other benefits are there with writing inline?
is it needed to state inline in order to reduce the executable file size, even though the compiler (according to wikipedia [I know, bad reference]) should find such functions itself?
Is there anything else I am missing?
To restate what I said in those little comment boxes. In particular, I was never talking about inlin-ing:
// foo.h:
static void f() {
// code that can't be inlined
}
// TU1 calls f
// TU2 calls f
Now, both TU1 and TU2 have their own copy of f - the code of f is in the executable two times.
// foo.h:
inline void f() {
// code that can't be inlined
}
// TU1 calls f
// TU2 calls f
Both TUs will emit specially marked versions of f that are effectively merged by the linker by discarding all but one of them. The code of f only exists one time in the executable.
Thus we have saved space in the executable.
Is inline just a recommendation for the compiler?
Yes.
7.1.2 Function specifiers
2 A function declaration (8.3.5, 9.3, 11.4) with an inline specifier declares an inline function. The inline
specifier indicates to the implementation that inline substitution of the function body at the point of call
is to be preferred to the usual function call mechanism. An implementation is not required to perform this
inline substitution at the point of call; however, even if this inline substitution is omitted, the other rules
for inline functions defined by 7.1.2 shall still be respected.
For example from MSDN:
The compiler treats the inline expansion options and keywords as suggestions. There is no guarantee that functions will be inlined. You cannot force the compiler to inline a particular function, even with the __forceinline keyword. When compiling with /clr, the compiler will not inline a function if there are security attributes applied to the function.
Note though:
3.2 One definition rule
3 [...]An inline function shall be defined in every translation unit in which it is used.
4 An inline function shall be defined in every translation unit in which it is used and shall have exactly
the same definition in every case (3.2). [ Note: a call to the inline function may be encountered before its
definition appears in the translation unit. —end note ] If the definition of a function appears in a translation
unit before its first declaration as inline, the program is ill-formed. If a function with external linkage is
declared inline in one translation unit, it shall be declared inline in all translation units in which it appears;
no diagnostic is required. An inline function with external linkage shall have the same address in all
translation units. A static local variable in an extern inline function always refers to the same object.
A string literal in the body of an extern inline function is the same object in different translation units.
[ Note: A string literal appearing in a default argument expression is not in the body of an inline function
merely because the expression is used in a function call from that inline function. —end note ] A type
defined within the body of an extern inline function is the same type in every translation unit.
[Note: Emphasis mine]
A TU is basically a set of headers plus an implementation file (.cpp) which leads to an object file.
Should it be explicitly stated when you have a small function (I
guess 1-4 instructions?)
Absolutely. Why not help the compiler help you generate less code? Usually, if the prolog/epilog part incurs more cost than having it inline force the compiler to generate them? But you must, absolutely must go through this GOTW article before getting started with inlining: GotW #33: Inline
What other benefits are there with writing inline?
namespaces can be inline too. Note that member functions defined in the class body itself are inline by default. So are implicitly generated special member functions.
Function templates cannot be defined in an implementation file (see FAQ 35.12) unless of course you provide a explicit instantiations (for all types for which the template is used -- generally a PITA IMO). See the DDJ article on Moving Templates Out of Header Files (If you are feeling weird read on this other article on the export keyword which was dropped from the standard.)
Is it needed to state inline in order to reduce the executable file
size, even though the compiler
(according to wikipedia [I know, bad
reference]) should find such functions
itself?
Again, as I said, as a good programmer, you should, when you can, help the compiler. But here's what the C++ FAQ has to offer about inline. So be wary. Not all compilers do this sort of analysis so you should read the documentation on their optimization switches. E.g: GCC does something similar:
You can also direct GCC to try to integrate all “simple enough” functions into their callers with the option -finline-functions.
Most compilers allow you to override the compiler's cost/benefit ratio analysis to some extent. The MSDN and GCC documentation is worth reading.
Is inline just a recommendation for the compiler?
Yes. But the linker needs it if there are multiple definitions of the function (see below)
Should it be explicitly stated when you have a small function (I guess 1-4 instructions?)
On functions that are defined in header files it is (usually) needed. It does not hurt to add it to small functions (but I don't bother). Note class members defined within the class declaration are automatically declared inline.
What other benefits are there with writing inline?
It will stop linker errors if used correctly.
is it needed to state inline in order to reduce the executable file size, even though the compiler (according to wikipedia [I know, bad reference]) should find such functions itself?
No. The compiler makes a cost/benefit comparison of inlining each function call and makes an appropriate choice. Thus calls to a function may be inlined in curtain situations and not inlined in other (depending on how the compilers algorithm works).
Speed/Space are two competing forces and it depends what the compiler is optimizing for which will determine weather functions are inlined and weather the executable will grow or shrink.
Also note if excessively aggressive inlining is used causing the program to expand too much, then locality of reference is lost and this can actually slow the program down (as more executable pages need to be brought into memory).
Multiple definition:
File: head.h
// Without inline the linker will choke.
/*inline*/ int add(int x, int y) { return x + y; }
extern void test()
File: main.cpp
#include "head.h"
#include <iostream>
int main()
{
std::cout << add(2,3) << std::endl;
test();
}
File: test.cpp
#include "head.h"
#include <iostream>
void test()
{
std::cout << add(2,3) << std::endl;
}
Here we have two definitions of add(). One in main.o and one in test.o
Yes. It's nothing more.
No.
You hint the compiler that it's a function that gets called a lot, where the jump-to-the-function part takes a lot of the execution time.
The compiler might decide to put the function code right where it gets called instead where normal functions are. However, if a function is inlined in x places, you need x times the space of a normal function.
Always trust your compiler to be much smarter than yourself on the subject of premature micro-optimization.
Actually, inline function may increase executable size, because inline function code is duplicated in every place where this function is called. With modern C++ compilers, inline mostly allows to programmer to believe, that he writes high-performance code. Compiler decides itself whether to make function inline or not. So, writing inline just allows us to feel better...
With regards to this:
And "inline" allows you to define the function multiple times in the program.
I can think of one instance where this is useful: Making copy protection code harder to crack. If you have a program that takes user information and verifies it against a registration key, inlining the function that does the verification will make it harder for a cracker to find all duplicates of that function.
As to other points:
inline is just a recommendation to compiler, but there are #pragma directives that can force inlining of any function.
Since it's just a recommendation, it's probably safe to explicitly ask for it and let the compiler override your recommendation. But it's probably better to omit it altogether and let the compiler decide.
The obfuscation mentioned above is one possible benefit of inlining.
As others have mentioned, inline would actually increase the size of the compiled code.
Yes, it will readily ignore it when it thinks the function is too large or uses incompatible features (exception handling perhaps). Furthermore, there is usually a compiler setting to let it automatically inline functions that it deems worthy (/Ob2 in MSVC).
It should be explicitly stated if you put the definition of the function in the header file. Which is usually necessary to ensure that multiple translation units can take advantage of it. And to avoid multiple definition errors. Furthermore, inline functions are put in the COMDAT section. Which tells the linker that it can pick just one of the multiple definitions. Equivalent to __declspec(selectany) in MSVC.
Inlined functions don't usually make the executable smaller. Since the call opcode is typically smaller than the inlined machined code, except for very small property accessor style functions. It depends but bigger is not an uncommon outcome.
Another benefit of in-lining (note that actual inlining is sometimes orthogonal to use of the "inline" directive) occurs when a function uses reference parameters. Passing two variables to a non-inline function to add its first operand to the second would require pushing the value of the first operand and the address of the second and then calling a function which would have to pop the first operand and address of the second, and then add the former value indirectly to the popped address. If the function were expanded inline, the compiler could simply add one variable to the other directly.
Actually inlining leads to bigger executables, not smaller ones.
It's to reduce one level of indirection, by pasting the function code.
http://www.parashift.com/c++-faq-lite/inline-functions.html