Difference between an inline function and static inline function - c++

Can anybody tell me what the difference is between an inline function and static inline function?
In which cases should I prefer static inline over inline?
I am asking this question because I have an inline function for which I am facing compilation issues during linking (relocation error:... symbol has been discarded with discarded section ...). I made it a normal function and it worked.
Now some of my seniors told me try with static inline.
Below is my function:
inline void wizSendNotifier (const char* nn_name, bpDU* arg=0, int aspect = -1)
{
wizuiNotifier* notifier = ::wizNtrKit.getNotifier (nn_name);
notifier->notify (arg, aspect);
}
and this not inside a class. This is inside a header file!
I guess the call to a static function should be done only in the particular TU where it is defined.
Since my function is in a header file and if i make it static, will it be the case that where ever I include that header file the static function can used used in that translation unit?

The non-static inline function declaration refers to the same function in every translation unit (source file) that uses it.
The One Definition Rule requires that the body of the function definition is identical in every TU that contains it, with a longish definition of "identical". This is usually satisfied provided that the source files all use the same header, and provided that the function doesn't use any global names with internal linkage (including static functions) or any macros that are defined differently in different TUs.
I don't remember encountering that particular linker error before, but it's at least possible that one of these restrictions is responsible. It's your responsibility to satisfy the requirements: undefined behavior with no diagnostic required if you don't.
The static inline function declaration refers to a different function in each translation unit, that just so happens to have the same name. It can use static global names or macros that are different in different TUs, in which case the function might behave differently in the different TUs, even though its definition in the header file "looks the same".
Because of this difference, if the function contains any static local variables then it behaves differently according to whether it is static or not. If it is static then each TU has its own version of the function and hence its own copy of the static local variables. If it's inline only, then there is only one copy of the static local variables used by all TUs.

Related

External Linkage of inline Functions/variables

I know what is static keyword means for functions.
But I cant understand what is inline keyword means for function.
I know that inline function is a function that
is expanded in line when it is called. But inline its offer for compiler, he can ignore it.
And perhaps compiler can optimize some functions and make it inline.
1) So why I need to declare functions inline, if compiler know better than me when need to function be inline, and when not ?
2) And I know inline functions have "external linkage" or something like that. what its mean ?
3) Does it make sense declare some functions inline static ?
The inline keyword is required to prevent violations of ODR (One Definition Rule). It doesn't relate to whether the function is actually inlined by the compiler, it merely tells the compiler that a definition is required in every translation unit.
With regards to "external linkage", this allows a static variable within an inline function to be shared across all translation units (which you would expect). If inline functions had "internal linkage" then each copy of the function (in each translation unit) would end up with it's own instance of the static variable, which wouldn't make much sense.

Static functions outside classes

Could someone tell me what's the purpose of declaring static functions outside classes? What's the difference between this 2? Are there any benefits for using static in this situation?
static void someRandomFunction();
int main()
{
someRandomFunction();
return 0;
}
and
void someRandomFunction();
int main()
{
someRandomFunction();
return 0;
}
At namespace scope, static gives a name internal linkage, meaning that it is only accessible within the translation unit that contains the definition. Without static, it has external linkage, and is accessible in any translation unit.
So you'd use static (or, alternatively, an unnamed namespace) when writing a function that's only intended for use within this unit; the internal linkage means that other units can define different functions with the same name without causing naming conflicts.
Non-static functions (and global names in general) are better declared in a header, to make sure that every translation unit that uses them gets the same declaration.
The static keyword on global functions or variables limits the visibility and linkage scope of the function or variable to the current translation unit.
That means that for a function, it can only be called from the current source file, and not from other source files.
A static function remains visible only in file scope. This is a C feature.
The recommended way to do it in C++ is using an anonymous namespace, as in:
namespace // no name, i.e. anonymous
{
void someRandomFunction();
}
int main()
{
someRandomFunction(); // visible only within this file.
return 0;
}
Note that the function body also has to be declared somewhere within the same file since the linker will not try to find it in other (external) translation units.
So void someRandomFunction(); is really a forward declaration for a function that is defined elsewhere in the same file (i.e. in the same translation unit).
If the function is actually called, you will get a linking error unless the function body is defined in the same file.
(The more pedantic technical term is actually not file but translation-unit since the body might be in an #includeed header do not in the actual file per-se. )
static void someRandomFunction();
This has to be used within same compilation unit (source file) and outside that compilation unit, not available for use.
Whereas, if you have
void someRandomFunction();
with one definition acrosss the program, the function can be used by any compilation unit globally across the program
Static methods and static functions are entirely different things.
Static methods are methods of a class instead of an instance (which you already know, as it seems).
Static functions, on the other hand, are function which are available only in the module they are defined in. They are not exported and cannot be put in a header file and used in another c file. This way you can write different functions sharing the same name, and also the compiler may optimize your code more thoroughly by inlining the function, knowing that no other file is dependant on it.
static tells the compiler not add the function to the symbol table for the object file. This effectively means that the linker is unable to find the function which in turn means you can only use the function directly in the current compilation unit. You can however call static functions from another compilation unit if this is done through a function pointer.

static vs inline for functions implemented in header files

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();

How does a compiler deal with inlined exported functions?

If a header file contains a function definition it can be inlined by the compiler. If the function is exported, the function's name and implementation must also be made available to clients during linkage. How does a compiler achieve this? Does it both inline the function and provide an implementation for external callers?
Consider Foo.h:
class Foo
{
int bar() { return 1; }
};
Foo::bar may be inlined or not in library foo.so. If another piece of code includes Foo.h does it always create its own copy of Foo::bar, whether inlined or not?
Header files are just copy-pasted into the source file — that's all #include does. A function is only inline if declared using that keyword or if defined inside the class definition, and inline is only a hint; it doesn't force the compiler to produce different code or prohibit you from doing anything you could otherwise do.
You can still take the address of an inline function, or equivalently, as you mention, export it. For those uses, the compiler simply treats it as non-inline and uses a One Definition Rule (the rule which says the user can't apply two definitions to the same function, class, etc) to "ensure" the function is defined once and only one copy is exported. Normally you are only allowed to have one definition among all sources; an inline function must have one definition which is repeated exactly in each source it is used.
Here is what the standard has to say about inline extern functions (7.1.2/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 defi- nition
appears in the translation unit. ] If
a function with external linkage is
declared inline in one transla- tion
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 an extern inline
function is the same object in
different translation units.
It usually means that it ends up creating a separate inlined method for every obj file that uses it at link time. It can also fail or refuse to inline many things, so this can cause a problem because you can wind up with bloated objs without getting the performance benefitting of inlining. The same thing can happen with virtual method inlining so it can be worth forcing inining and setting warning for inline failure (about the only useful warning message compilers give).
By export, I'm guessing you mean something such as getting a pointer to the function and later calling the function through the pointer.
Yes, in that case, the compiler will generate a regular function so that it can be invoked from a pointer.
One way to do this is with a link-once section. The idea is that in translation unit gets the code in a special type of section that has a name based on the function name. During linking, the linker will only keep one instance of identically named link-once sections.
inlined functions do not exist in the compiled binary: that is because they are taken and placed directly at the call site (so called IN-LINE). Each usage of the inlined function results in the complete code to be pulled in at that place.
So inlined functions cannot be exported because they do not exist. But you can still use them if you have a definition in one header. And yes, you MUST provide a definition for an inlined function, otherwise you cannot use it.
If you managed to export an inlined function then it is sure that it is not inline anymore: inline is not a strict semantic element. Depending on the compiler and compiler settings, one compiler might choose to inline, another not, sometimes provide a warning, sometimes even an error (which personnally I would prefer being the default behaviour, because it shows up the places where unintended things occur)

Inline member functions in C++

ISO C++ says that the inline definition of member function in C++ is the same as declaring it with inline. This means that the function will be defined in every compilation unit the member function is used. However, if the function call cannot be inlined for whatever reason, the function is to be instantiated "as usual". (http://msdn.microsoft.com/en-us/library/z8y1yy88%28VS.71%29.aspx) The problem I have with this definition is that it does not tell in which translation unit it would be instantiated.
The problem I encountered is that when facing two object files in a single static library, both of which have the reference to some inline member function which cannot be inlined, the linker might "pick" an arbitrary object file as a source for the definition. This particular choice might introduce unneeded dependencies. (among other things)
For instance:
In a static library
A.h:
class A{
public:
virtual bool foo() { return true; }
};
U1.cpp:
A a1;
U2.cpp:
A a2;
and lots of dependencies
In another project
main.cpp:
#include "A.h"
int main(){
A a;
a.foo();
return 0;
}
The second project refers the first. How do I know which definition the compiler will use, and, consequently which object files with their dependencies will be linked in? Is there anything the standard says on that matter? (Tried, but failed to find that)
Thanks
Edit: since I've seen some people misunderstand what the question is, I'd like to emphasize: If the compiler decided to create a symbol for that function (and in this case, it will, because of 'virtualness', there will be several (externally-seen) instantiations in different object file, which definition (from which object file?) will the linker choose?)
Just my two cents. This is not about virtual function in particular, but about inline and member-functions generally. Maybe it is useful.
C++
As far as Standard C++ is concerned, a inline function must be defined in every translation unit in which it is used. And an non-static inline function will have the same static variables in every translation unit and the same address. The compiler/linker will have to merge the multiple definitions into one function to achieve this. So, always place the definition of an inline function into the header - or place no declaration of it into the header if you define it only in the implementation file (".cpp") (for a non-member function), because if you would, and someone used it, you would get a linker error about an undefined function or something similar.
This is different from non-inline functions which must be defined only once in an entire program (one-definition-rule). For inline functions, multiple definitions as outlined above are rather the normal case. And this is independent on whether the call is atually inlined or not. The rules about inline functions still matter. Whether the Microsoft compiler adheres to those rules or not - i can't tell you. If it adheres to the Standard in that regard, then it will. However, i could imagine some combination using virtual, dlls and different TUs could be problematic. I've never tested it but i believe there are no problems.
For member-functions, if you define your function in the class, it is implicitly inline. And because it appears in the header, the rule that it has to be defined in every translation unit in which it is used is automatically satisfied. However, if you define the function out-of-class and in a header file (for example because there is a circular dependency with code in between), then that definition has to be inline if you include the corresponding file more than once, to avoid multiple-definition errors thrown by the linker. Example of a file f.h:
struct f {
// inline required here or before the definition below
inline void g();
};
void f::g() { ... }
This would have the same effect as placing the definition straight into the class definition.
C99
Note that the rules about inline functions are more complicated for C99 than for C++. Here, an inline function can be defined as an inline definition, of which can exist more than one in the entire program. But if such a (inline-) definition is used (e.g if it is called), then there must be also exactly one external definition in the entire program contained in another translation unit. Rationale for this (quoting from a PDF explaining the rationale behind several C99 features):
Inlining in C99 does extend the C++ specification in two ways. First, if a function is declared inline in one translation unit, it need not be declared inline in every other translation unit. This allows, for example, a library function that is to be inlined within the library but available only through an external definition elsewhere. The alternative of using a wrapper function for the external function requires an additional name; and it may also adversely impact performance if a translator does not actually do inline substitution.
Second, the requirement that all definitions of an inline function be "exactly the same" is replaced by the requirement that the behavior of the program should not depend on whether a call is implemented with a visible inline definition, or the external definition, of a function. This allows an inline definition to be specialized for its use within a particular translation unit. For example, the external definition of a library function might include some argument validation that is not needed for calls made from other functions in the same library. These extensions do offer some advantages; and programmers who are concerned about compatibility can simply abide by the stricter C++ rules.
Why do i include C99 into here? Because i know that the Microsoft compiler supports some stuff of C99. So in those MSDN pages, some stuff may come from C99 too - haven't figured anything in particular though. One should be careful when reading it and when applying those techniques to ones own C++ code intended to be portable C++. Probably informing which parts are C99 specific, and which not.
A good place to test small C++ snippets for Standard conformance is the comeau online compiler. If it gets rejected, one can be pretty sure it is not strictly Standard conforming.
When you have an inline method that is forced to be non-inlined by the compiler, it will really instantiate the method in every compiled unit that uses it. Today most compilers are smart enough to instantiate a method only if needed (if used) so merely including the header file will not force instantiation. The linker, as you said, will pick one of the instantiations to include in the executable file - but keep in mind that the record inside the object module is of a special kind (for instance, a COMDEF) in order to give the linker enough information to know how to discard duplicated instances. These records will not, therefore, result in unwanted dependencies between modules, because the linker will use them with less priority than "regular" records to resolve dependencies.
In the example you gave, you really don't know, but it doesn't matter. The linker won't resolve dependencies based on non-inlined instances alone ever. The result (in terms of modules included by the linker) will be as good as if the inline method didn't exist.
AFAIK, there is no standard definition of how and when a C++ compiler will inline a function call. These are usually "recommendations" that the compiler is in no way required to follow. In fact, different users may want different behaviors. One user may care about speed, while another may care about small generated object file size. In addition, compilers and platforms are different. Some compilers may apply smarter analysis, some may not. Some compilers may generate longer code from the inline, or work on a platform where calls are too expensive, etc.
When you have an inline function, the compiler should still generate a symbol for it and eventually resolve a single version of it. So that if it is in a static library, people can still call the function not in inline. In other words, it still acts as a normal function,.
The only effect of the inline is that some cases, the compiler will see the call, see the inline, and skip the call completely, but the function should still be there, it's just not getting called in this case.
If the compiler decided to create a symbol for that function (and in this case, it will, because of 'virtualness', there will be several (externally-seen) instantiations in different object file, which definition (from which object file?) will the linker choose?)
The definition that is present in the corresponding translation unit. And a translation unit cannot, and I repeat, cannot have but exactly one such definition. The standard is clear about that.
[...]the linker might "pick" an arbitrary object file as a source for the definition.
EDIT: To avoid any further misunderstanding, let me make my point clear: As per my reading of the standard, the ability to have multiple definition across different TUs does not give us any practical leverage. By practical, I mean having even slightly varying implementations. Now, if all your TUs have the exact same definition, why bother which TU the definition is being picked up from?
If you browse through the standard you will find the One Definition Rule is applied everywhere. Even though it is allowed to have multiple definitions of an inline function:
3.2 One Definition Rule:
5 There can be more than one definition of a class type (Clause 9), concept (14.9), concept map (14.9.2), enumeration type (7.2), inline function with external linkage (7.1.2), [...]
Read it in conjunction with
3 [...] An inline function shall be defined in every translation unit in which it is used.
This means that the function will be defined in every compilation unit [...]
and
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.
3 A function defined within a class definition is an inline function. The inline specifier shall not appear on a block scope function declaration.[footnote: 82] If the inline specifier is used in a friend declaration, that declaration shall be a definition or the function shall have previously been declared inline.
and the footnote:
82) The inline keyword has no effect on the linkage of a function.
§ 7.1.2 138
as well as:
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 ]
Distilled: Its ok to have multiple definitions, but they must have the same look and feel in every translation unit and address -- but that doesn't really give you much to cheer about. Having multiple deinition across translation units is therefore not defined (note: I am not saying you are invoking UB, yet).
As for the virtual thingy -- there won't be any inlining. Period.
The standard says:
The same declaration must be available
There must be one definition
From MSDN:
A given inline member function must be declared the same way in every compilation unit. This constraint causes inline functions to behave as if they were instantiated functions. Additionally, there must be exactly one definition of an inline function.
Your A.h contains the class definition and the member foo()'s definition.
U1.cpp and U2.cpp both define two different objects of class A.
You create another A object in main(). This is just fine.
So far, I have seen only one definition of A::foo() which is inline. (Remember that a function defined within the class declaration is always inlined whether or not it is preceded by the inline keyword.)
Don't inline your functions if you want to ensure they get compiled into a specific library.