Should one never use static inline function?
Solution 1
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
Solution 2
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.
Solution 3
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
Solution 4
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
}
Solution 5
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.
Related videos on Youtube
Alok Save
Alok is a long time C & C++ enthusiast.He wrote his first commercial C++ program more than a decade ago and has been in love with C++ ever since. He is known to dabble in Java,Pro-C,SQL,PLSQL,Unix scripting & many more languages.He has worked in various technical roles ranging from a programmer to a technical solutions architect.In his spare time he loves answering questions,especially on C & C++. -:Alok's LinkedIn:- SO Milestones: c++ Gold Badge (18/07/2011) c Gold Badge (02/01/2011) legendary Legendary Badge (29/05/2012) Some personal favorite answers:- Why I can't initialize non-const static member or static array in class? When to mark a function in C++ as a virtual? Previous definition error Destructor not invoked when an exception is thrown in the constructor Contribution to c++-faq :- What are Access specifiers? Should I inherit with private,protected or public? Why should one replace default new and delete operators? How should I write ISO C++ Standard conformant custom new and delete operators? What is this weird colon-member syntax in the constructor? What is the difference between char a[] = "string"; and "char *p = string;" External links he likes/recommends: C++ Faq Bjarne Stroustrup's C++ Style and Technique FAQ Bjarne Stroustrup's general faq C-Faq Clockwise Spiral Rule What Every Programmer Should Know About Floating-Point Arithmetic
Updated on May 13, 2020Comments
-
Alok Save about 4 years
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 asstatic inline
function,The
static
keyword on the function forces theinline
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 keywordinline
has no importance anymore, it becomes redundant.So, Practically marking a function
static
andinline
both has no use at all. Either it should bestatic
(not most preferred) orinline
(most preferred),
So, Is usingstatic
andinline
together on a function practically useless?-
Mars almost 12 yearsWhere does the snippet "and each instance of these functions have their own copies of static local variables & string literals" come from?
-
Nawaz almost 12 yearsIs this what the Standard says >> 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.
-
Alok Save almost 12 years@JonasByström: § 7.1.3/4 "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*". A function marked
static
has no external linkage, so inverse applies. -
Alok Save almost 12 years@Nawaz: No that is not what standard says(I nowhere claimed it does), I am saying that and it is based on behavior of most of the mainstream compilers.Usually the standard does not say anything about implementations it only talks about observable behaviors This Q is about practicality.
-
Abhijit-K almost 12 yearsStill not getting this >>"and each instance of these functions have their own copies of static local variables & string literals". Someone help me understand. If somehow we have functions having copies of static variable and these functions also modify them (static variable) then how can the value of static variable be in sink?
-
Sam Kauffman about 11 yearsThought I'd add for clarity that this question is about
static
inline
functions that are not class methods. Forstatic
inline
methods, look here.
-
Alok Save almost 12 yearsBut usually, One would add
inline
on the *definition*(cpp file) & not the *declaration*(header) of the function, So How does it help in being descriptive to users of my code? It might be useful to one who can see the source files only. -
Mac almost 12 years@Als: regardless of where it appears, it is more useful to maintainers of code, in order to declare intended or assumed behaviour of the code. It's not so useful for users of the code - whether the function's inline or not shouldn't (ideally) matter to them.
-
Potatoswatter almost 12 years@Als A
static
function is usually not declared in the header file, so the declaration is optional and there's little difference anyway. Aninline
function must be declared and defined in the same file, so the same again applies. Also, that sounds like a really bad idea. If you want to choose one or the other, mark the declaration inline. Of course it's better to mark both. -
Alok Save almost 12 years@Potatoswatter: I am all for marking functions
inline
overstatic
or anonymous namespace.inline
is the most correct way to have a function definition in the header file.My Q is just aboutstatic inline
being practically useless apart from as you said just perhaps being vocal of the intent. -
Alok Save almost 12 yearsI do not understand your answer,Can you please elaborate in detail What is different and How it is different?
-
Suma almost 12 yearsIf disagree inline is useless. It is "only" a hint, but still, it is a hint, and compilers give some value to this hint.
-
Potatoswatter almost 12 years@Als:
static
andnamespace{}
do (roughly) the same thing.inline
does something else. Don't underestimate the value of describing intent. If you must have effects, aninline
declaration is likely to make the compiler more aggressive about inlining. From what you've said so far, it sounds like you might have been misusing these specifiers for functions with declarations in a.h
and definitions in a.cpp
, which is wrong. -
Suma almost 12 years"compiler mostly ignores that hint" This depends on the compiler and the setting used. When you use a Visual Studio with /Ob1, the compiler complies to the hint.
-
iammilind almost 12 years@Suma, do you mean that, if you hint
inline
then MSVS inlines a recursive function call also (#1 effect in OP) with/Ob1
? It's impossible. There can be other such cases where the function will not be replaced by its definition (e.g. function body is too big and is invoked at various places). There is no value of a hint. The only guaranteed effect ofinline
is #2 (from OP). -
Suma almost 12 yearsWith /Ob1 inline is a hint the funcion can be inlined. Without being marked as inline the funcion is never inlined.
-
Alok Save almost 12 yearsThanks, I understand but Perhaps: "static implies that multiple functions with the same name may exist with different definitions without breaking the ODR" is better?
-
Johannes Schaub - litb almost 12 yearsthere is no notion of preference of an unnamed namespace over static. both have the same effect wrt linkage.
-
Johannes Schaub - litb almost 12 years@als "without breaking the odr" does not make sense because the odr does not disallow it.
-
Potatoswatter almost 12 years@JohannesSchaub-litb Well they're not necessarily exactly the same. They achieve the same thing wrt visibility between TUs within C++, but ABI/binary format effects may differ.
static
isn't guaranteed to generate a visible, unique name likenamespace{}
is. What was the reason for the un-deprecation? Was it ADL name association, the need to have the feature for language linkage, or something else? If ADL, isn't that fixed byinline
namespaces? -
Robert Calhoun over 10 yearsInterestingly your suggestion to use
static inline
as a replacement for macros is specifically recommended under this linux kernel style guide. ("Static inline functions are greatly preferred over macros. They provide type safety, have no length limitations, no formatting limitations, and under gcc they are as cheap as macros."). -
M.M almost 10 years"What is preferred is to use an unnamed namespace instead of static:" - preferred by whom, and why? Neither version should generate a name visible outside the TU.
-
Potatoswatter almost 10 years@MattMcNabb Preferred by the committee that deprecated that usage of
static
back in 1998, and anyone who agrees with the comments in my example. I've yet to see an argument in favor ofstatic
. -
Z boson over 8 years@AlokSave, why do you say " I am all for marking functions inline over static or anonymous namespace"? The compiler can optimize static functions further. On the other hand static functions may make the code longer. Doesn't it depend on what your goal is? In may case I am almost always after efficiency otherwise I would use another language than C++.
-
Z boson over 8 years@Potatoswatter, you write "A static function is usually not declared in the header file". What's wrong with putting static functions in the header file?
-
Potatoswatter over 8 years@Zboson You might be confusing
static
withinline
. Please open a new question and provide an example. -
Z boson over 8 years@Potatoswatter, no I don't think I am. I mean static functions in a header file.
-
Arvid almost 8 yearsthe inline keyword in C has different semantics than C++. It's more complicated to have inline functions with external linkage in C, because the you have to manually pick the translation unit/object file where the non-inlined version is put. I believe the recommendation of using static inline is C-centric, and mostly motivated by convenience. Presumably it increases the risk of code duplication in the binary
-
Potatoswatter about 7 years@Zboson A
static
function declared in a header file must also be defined there, so it will be compiled and linked separately for each TU. Especially if it's too big to beinline
, it may bloat the executable size and build time. (Sorry for the late reply.) -
Z boson about 7 years@Potatoswatter, I am aware of that. That's often what I want (each TU to optimize the static function as best it can and inline the code). Agner Fog built his VectorClass library as essentially several header files using
static inline
for each function (thoughstatic
would be sufficient) agner.org/optimize/vectorclass.zip. -
Z boson about 7 years"Using
static inline
makes sense when the inlined function is not used outside of the translation unit."static
makes sense, addinginline
to it is pointless. -
Potatoswatter about 7 years@Zboson Again, there seems to be some confusion here between the effects of
static
andinline
. In a C header library, addingstatic
toinline
may help by eliminating the need for an additional non-inline
definition. But C++ doesn't have such a need, and using different functions in different TUs (perstatic
) as if they were the same function, multiply defined (the usual behavior ofinline
) often violates the ODR. That library likely contains undiagnosed ODR violations, and usage of it certainly does. -
Leushenko almost 7 yearsI have to -1 this because there's no justification at all given for why adding
inline
tells a maintainer anything.inline
has no effect on the optimization behaviour of any remotely recent compiler, and it's essentially none of the author's business how the code is generated or arguably whether such concepts even still apply to the heavily-rewritten output. It's not obvious how inlining has anything at all to do with maintenance because it's not obvious how it's in any way relevant to the code's "intent" in the first place. -
Chris almost 6 yearsHow about structs being first class citizens within functions, and declaring local structs allows for local functors which avoid all the binding, lambdas, etc.
static
is the only thing which allows for this approach. -
jww almost 5 yearsI believe you are not supposed to use anonymous namespaces in header-only implementations.
-
Potatoswatter almost 5 years@jww And for the same reason never
static
functions either. -
Eyal over 3 yearsIf you want to replace a macro,
extern inline
is a better fit. The difference is thatstatic inline
makes a version that isn't inline and the compiler can choose to use either. Withextern inline
, the non-inline version won't even exist. -
0xC0000022L over 2 years... but also inlining the code everywhere it gets called and so increasing the size of the generated code by that bit. No?