Is it possible to force a function not to be inlined?
In Visual Studio 2010, __declspec(noinline)
tells the compiler to never inline a particular member function, for instance:
class X {
__declspec(noinline) int member_func() {
return 0;
}
};
edit: Additionally, when compiling with /clr
, functions with security attributes never get inlined (again, this is specific to VS 2010).
I don't think it will prove at all useful at debugging, though.
__declspec(noinline)
for VC++. Contrary to the man page, this appears to work for freestanding functions, and I don't think I've ever used it for a member function. You may -- though note that I never have -- want to consider playing with the optimization flags too, so that only inline
functions are considered for inlining, though of course this has a global effect and that may not be what you want.
__attribute__((noinline))
for gcc (and a number of less-common compilers that support the gcc attribute syntax). I must admit, I don't think I've ever actually used this, but it appears to be there.
(Of course, these two styles of annotation go in different places, so it's a bit annoying to construct code that's palatable to both.)
I'm not sure how either of these interact with the inline
C++ keyword; I've only used them when debugging (when I just want a particular non-inline function left not inline after optimization) or when examining generated code (and I'm getting confused because random stuff is being inlined).
Please remember that inlining is relevant at the function call site, the same function can be inlined in some situations and not inlined in other.
If your function is visible outside the compilation unit then even if it's inlined in all the current places it's used, the body of the function must still be available for anyone who wants to call it later on (by linking with the object file).
In order to have a call site not inlined you can use a pointer to a function.
void (*f_ptr)(int); // pointer to function
volatile bool useMe = true; // disallow optimizations
if (useMe)
f_ptr = myFunc;
else
f_ptr = useOtherFunc;
f_ptr(42); // this will not be inlined
[[gnu::noinline]]
attribute
We can also use the C++11 attribute specifier syntax with the non-standard gnu::noinline
attribute: https://en.cppreference.com/w/cpp/language/attributes
It is just a matter of time until that gnu::
part gets dropped a future C++ standard to give a standardized [[noinline]]
:-)
main.cpp
[[gnu::noinline]]
int my_func() {
return 1;
}
int main() {
return my_func();
}
Compile and disassemble:
g++ -ggdb3 -O3 -o main.out -std=c++11 -Wall -Wextra -pedantic-errors main.cpp
gdb -batch -ex 'disassemble/r main' main.out
With [[gnu::noinline]]
:
0x0000000000001040 <+0>: f3 0f 1e fa endbr64
0x0000000000001044 <+4>: e9 f7 00 00 00 jmpq 0x1140 <my_func()>
Without [[gnu::noinline]]
:
0x0000000000001040 <+0>: f3 0f 1e fa endbr64
0x0000000000001044 <+4>: b8 01 00 00 00 mov $0x1,%eax
0x0000000000001049 <+9>: c3 retq
Tested on Ubuntu 19.10.