When can/will a function be inlined in C++? Can inline behavior be forced?

254 views Asked by At

I am trying to get the expected behavior when I use the keyword inline. I tried calling a function in different files, templating the function, using different implementation of the inline function, but whatever I do, the compiler is never inlining the function.

So in which case exactly will the compiler chose to inline a function in C++ ?

Here is the code I have tried :

inline auto Add(int i) -> int {
  return i+1;
}

int main() {  
  Add(1);  
  return 0;
}

In this case, I get:

Add(int):
    pushq   %rbp
    movq    %rsp, %rbp
    movl    %edi, -4(%rbp)
    movl    -4(%rbp), %eax
    addl    $1, %eax
    popq    %rbp
    ret
main:
    pushq   %rbp
    movq    %rsp, %rbp
    movl    $1, %edi
    call    Add(int)
    movl    $0, %eax
    popq    %rbp
    ret

Or again,

template<typename T>
inline auto Add(const T &i) -> decltype(i+1) {
  return i+1;
}

int main() {  
  Add(1);  
  return 0;
}

And I got:

main:
    pushq   %rbp
    movq    %rsp, %rbp
    subq    $16, %rsp
    movl    $1, -4(%rbp)
    leaq    -4(%rbp), %rax
    movq    %rax, %rdi
    call    decltype ({parm#1}+(1)) Add<int>(int const&)
    movl    $0, %eax
    leave
    ret
decltype ({parm#1}+(1)) Add<int>(int const&):
    pushq   %rbp
    movq    %rsp, %rbp
    movq    %rdi, -8(%rbp)
    movq    -8(%rbp), %rax
    movl    (%rax), %eax
    addl    $1, %eax
    popq    %rbp
    ret

I used https://gcc.godbolt.org/ to get the assembly code here, but I also tried on my machine with clang and gcc (with and without optimization options).

EDIT:

Ok, I was missing something with the optimization options. If I set GCC to use o3 optimization level, my method is inlined.

But still. How does GCC, or another compiler, know when it is better to inline a function or not ?

2

There are 2 answers

0
Yogesh On BEST ANSWER

As a rule, your code is always inlined only if you specify:

__attribute__((always_inline))

eg (from gcc documentation):

inline void foo (const char) __attribute__((always_inline));

Though it is almost never a good idea to force your compiler to inline your code.

You may set a high optimization level (though the O flag) to achieve maximum inlining, but for more details please see the gcc documentation

Inlining is actually controlled by a number of parameters. You can set them using the -finline-* options. You can have a look at them here

2
CHKingsley On

By the way, you did not actually declare a function. You declared a functor, an object that can be called, but can also store state. Instead of using the syntax:
inline auto Add(int i) -> int {

you mean to say simply:
inline int Add(int i) {