pimpl 中的方法是内联的吗?
考虑下一个简单的例子:
标题:
// 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
实现:
// 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();
}
主要:
// main.cpp
#include "header.hpp"
int main()
{
A a;
return a.foo();
}
问题是:
方法 A::Imp::foo
是否会内联到 A::foo
中?
这是否取决于该方法中的实现?
聚苯乙烯 我正在使用 gcc(4.3.0,如果重要的话)。
编辑
我想我没有解释得很好。我真正的意思是这样的。如果我使用最大优化级别,则 // do something and return the result
将被放置在 A::foo()
或 A: :Imp::foo()
?
如果没有优化,我发现这还没有完成(仍然调用 pimpl->foo() )。
我知道 A::foo() 永远不会内联到 main() 中,但这不是我要问的。
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
Herb Sutter 曾经写过一篇关于内联的精彩文章。
首先要问的问题是:内联什么时候可以发生?
在 C++ 中:
,两次的机制都是相似的:如果编译器/链接器知道该方法的实现,它可能会决定复制/粘贴实现来代替发出调用。这个决定是基于复杂的启发法,我只知道它们存在,而不知道它们是什么。
因此,关键点是了解实现位。
所以这里:是的,调用
pimpl->foo()
可以内联在A::foo
中。它将取决于编译器和编译选项。对于 gcc/clang,如果
A::Impl::foo
足够小,则可以从 O1 开始进行优化(除非您传递-fno-inline
)。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 withinA::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
).所有内联都依赖于实现。如果这对您很重要,请查看发出的汇编代码。
All inlining is implementation dependent. If this matters to you, look at the emitted assembler code.