Home > OS >  using `[[gnu::noinline]]` in header-only library
using `[[gnu::noinline]]` in header-only library

Time:05-21

Functions in a header-only library should be declared as inline to prevent multiple definitions in the different translation units. That is, for example, I wrote a header-only library mylib.hpp:

void do_something(int) {}

And I used this header in two different cpp file:

// a.cpp
# include "mylib.hpp"
void func1() {do_something(1);}
// b.cpp
# include "mylib.hpp"
void func2() {do_something(2);}

Build them with g -o main a.cpp b.cpp, GCC will complain with "multiple definition of do_something(int)". To prevent this, define the function like static void do_something(int) {} to make it have a copy in each translation unit (that is, have two copies in the last output), or define the function like inline void do_something(int) {} to have exactly a single copy in the last output, which is what we want.

However, if I want to force do_something not to be inlined by the compiler (for example, I want to use backtrace library to dynamically find out which function called do_something), I should write it like:

[[gnu::noinline]] inline void do_something(int) {}

However, GCC complains:

Warning: inline declaration of ‘do_something(int)’ follows declaration with attribute ‘noinline’ [-Wattributes]

So, what is the proper way to do such things?

CodePudding user response:

The inline keyword does not mean the code must be inlined or that it even will. inline says that there may be multiple (identical) versions of this functions and the linker will pick at most one representative.

The compiler can inline the function if it thinks it's worth it and inline can make it more likely to be inline. But why not let the compiler decide? It doesn't inline functions without reason.

But if you must have you tried static? A static function will not be exported to the outside of the translation unit. Every translation unit can have a static version of the same function without conflict. But be aware that that will be many copies of the same function and each has a unique address.

CodePudding user response:

if I want to force do_something not to be inlined by the compiler

There is no portable way to do that.

inline has a confusing name, it's not about inlining. You want just:

[[gnu::noinline]] static void do_something(int) {}

I want to use backtrace library to dynamically find out which function called do_something

There is artificial funciton attribute https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#Common-Function-Attributes .

what is the proper way to do such things?

The proper way of defining a function in a header is with a static keyword.

If you mean by not-inlining a function, you don't - compilers optimize code, functions get inlined. If you want a fuction to be available for debugging, you configure compiler not to inline the code (-fno-inline, if you want to force it).

  • Related