Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are methods in the pimpl inlined?

Considering next simple example:

The header:

// a.hpp
#ifndef A_HPP
#define A_HPP
#include <memory>

class A
{
 public:
  A();

  int foo();

 private:
  struct Imp;
  std::auto_ptr< Imp > pimpl;
};

#endif // A_HPP

The implementation :

// a.cpp
#include "a.hpp"

struct A::Imp
{
 int foo()
 {
  // do something and return the result
 }
};

A::A() : pimpl( new Imp )
{}
int A::foo()
{
  return pimpl->foo();
}

The main :

// main.cpp
#include "header.hpp"
int main()
{
  A a;
  return a.foo();
}

The questions are :
Is the method A::Imp::foo going to get inlined into A::foo?
Does it depend on the implementation what is in that method?

PS I am using gcc (4.3.0 if it matters).

EDIT

I guess I didn't explain very well. What I exactly meant is this. If I use the maximum optimization level, is the // do something and return the result going to be placed in the A::foo() or A::Imp::foo()?
Without optimization, I see that this is not done (the pimpl->foo() is still called).

I understand that A::foo() will never get inlined in main(), but that is not what I am asking.

like image 436
BЈовић Avatar asked Nov 30 '22 08:11

BЈовић


1 Answers

Herb Sutter once made a great article about inlining.

The first question to ask is: when can inlining happen ?

In C++:

  • it may happen at the compilation stage
  • it may happen at the link stage (LTO: Link Time Optimization)

Both times, the mechanism is similar: if the compiler/linker knows about the implementation of the method, it may decide to copy/paste the implementation in place of emitting a call. This decision is based on complex heuristics, and I only know they exist, not what they are about.

The critical point is therefore the knows about the implementation bit.

  • for the compiler: it means defined in the same translation unit
  • for the linker: it means defined in one of the translation units being linked OR in a static library it will linked to... afaik it won't be optimized if the method resides in a DLL

So here: yes, the call pimpl->foo() may be inlined within A::foo. It will depend on both the compiler and the compiling options.

For gcc/clang, if A::Impl::foo is small enough, it could be optimized from O1 onward (unless you pass -fno-inline).

like image 180
Matthieu M. Avatar answered Dec 20 '22 04:12

Matthieu M.