pimpl 中的方法是内联的吗?

发布于 2024-11-14 04:56:17 字数 973 浏览 5 评论 0原文

考虑下一个简单的例子:

标题:

// 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

一杆小烟枪 2024-11-21 04:56:17

Herb Sutter 曾经写过一篇关于内联的精彩文章。

首先要问的问题是:内联什么时候可以发生?

在 C++ 中:

  • 它可能发生在编译阶段
  • ,也可能发生在链接阶段(LTO:链接时间优化)

,两次的机制都是相似的:如果编译器/链接器知道该方法的实现,它可能会决定复制/粘贴实现来代替发出调用。这个决定是基于复杂的启发法,我只知道它们存在,而不知道它们是什么。

因此,关键点是了解实现位。

  • 对于编译器:这意味着在
  • 链接器的同一翻译单元中定义:这意味着在链接的翻译单元之一中定义或在它将链接到的静态库中定义...据我所知,如果该方法驻留在其中,则不会被优化在 DLL 中

所以这里:是的,调用 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++:

  • 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).

流云如水 2024-11-21 04:56:17

所有内联都依赖于实现。如果这对您很重要,请查看发出的汇编代码。

All inlining is implementation dependent. If this matters to you, look at the emitted assembler code.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文