Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

static vs inline for functions implemented in header files

Tags:

c++

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.

like image 256
void.pointer Avatar asked Feb 28 '14 18:02

void.pointer


People also ask

Should static functions be declared in header?

Typically, static functions are functions needed in only one file. They are declared static to make that explicit by limiting their visibility. Declaring them in a header therefore is somewhat antithetical.

Do inline functions need to be in header?

Note: It's imperative that the function's definition (the part between the {...} ) be placed in a header file, unless the function is used only in a single . cpp file. In particular, if you put the inline function's definition into a . cpp file and you call it from some other .

Do inline functions need to be static?

In C99, an inline or extern inline function must not access static global variables or define non- const static local variables. const static local variables may or may not be different objects in different translation units, depending on whether the function was inlined or whether a call was made.

Why is header inline static?

A static inline function is, in practice, likely (but not certain) to be inlined by some good optimizing compiler (e.g. by GCC when it is given -O2 ) at most of its call sites. It is defined in a header file, because it then could be inlined at most call sites (perhaps all of them).


3 Answers

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).

like image 139
jalf Avatar answered Oct 12 '22 19:10

jalf


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.

like image 34
Chris Dodd Avatar answered Oct 12 '22 18:10

Chris Dodd


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.

like image 7
joeking Avatar answered Oct 12 '22 19:10

joeking