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.
Herb Sutter once made a great article about inlining.
The first question to ask is: when can inlining happen ?
In C++:
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.
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
).