C++隐含内联函数

hqt*_*hqt 3 c++ inline

我在文档中读到了关于内联函数的内容.我的文档说:有两种类型的内联函数:implicity functionexplicity function.

Explicity function:你inline在函数之前使用关键字,并在类之外使用.例如:

inline int Math::add(int a, int b){ return a + b; }
Run Code Online (Sandbox Code Playgroud)

Implicity function:类中的每个方法都是隐含的.例如:

class Math {
   int add(int a, int b) { return a + b;}   // implicity inline function
};
Run Code Online (Sandbox Code Playgroud)

所以,如果这是真的,那么,我不想使用的每一种方法,我都inline必须在课堂外宣布,对吧?如果这是真的,我可以在类中实现一个方法而不需要内联函数.

谢谢 :)

Ell*_*ioh 7

保证它不是内联的唯一方法是在编译时使其无法访问,例如,将其主体定义放入cpp文件而不是标头.

更新:一位评论者表示,即使将函数体放入不同的编译单元也无法保证有所帮助.他是绝对正确的.通常它会有所帮助,但有些编译器仍然可以内联函数.因此,没有可靠的方法来禁用不依赖于编译器的内联.

所有内联只是一个优化问题.如果启用了适当的优化,通过编写内联关键字,您只需告诉编译器您推荐内联函数.您既不能强制编译器内联函数,也不能强制编译器不内联它.对于某些编译器,例如VC++,有一些方法可以这样做(__declspec(noinline)),但它们都依赖于编译器.

为什么需要禁用内联?编译器通常知道更好...如果它是出于调试目的,只需禁用优化,或者至少是函数内联.您甚至可以使用编译指示在单个文件中执行此操作.无论如何,通常应该避免调试发布版本,当然有时候无法避免它.

  • 有_no_方式来保证函数是否内联.语言标准根据可观察行为定义正确性,函数是否内联对可观察行为没有影响.(有些编译器会在不同的转换单元中定义内联函数,根据分析器输出选择要内联的函数.) (2认同)

Vyk*_*tor 5

阅读C ++标准,如何定义“隐式内联函数”:

成员函数可以在其类定义中定义(8.4),在这种情况下,它是一个内联成员函数(7.1.2),或者可以在其类定义之外定义(如果已经声明但未在其定义中定义)。类定义。出现在类定义之外的成员函数定义应出现在包含类定义的名称空间范围内。除了出现在类定义之外的成员函数定义外,除了出现在类定义之外的类模板的成员函数和成员函数模板的显式特化(14.7)外,不得重新声明成员函数。

同样,编译器也不保证它会真正执行替换:

具有内联说明符的函数声明(8.3.5、9.3、11.4)声明了内联函数。内联说明符向实现指示,在调用点处对函数体进行内联替换比通常的函数调用机制更可取。 在调用点不需要执行此内联替换的实现;但是,即使省略了此内联替换,仍应遵守7.1.2定义的其他内联函数规则。

其他所有功能都可能是“非内联”的,尽管一旦打开优化功能,可能会发生很多奇怪的事情,例如,看看gcc-Optimize options

  • -finline-small-functions 作为一部分 O2

    当函数的主体小于预期的函数调用代码时,将函数集成到其调用程序中(因此程序的整体大小会变小)。编译器会试探性地确定哪些功能足够简单,值得以这种方式进行集成。该内联适用于所有函数,甚至包括那些未声明为内联的函数。

  • -finline-functions 作为一部分 O3

    考虑将所有函数都内联,即使未声明为内联也是如此。编译器会试探性地决定哪些函数值得以这种方式集成。
    如果集成了对给定函数的所有调用,并且将该函数声明为静态,则该函数通常不会单独作为汇编代码输出。

  • -finline-functions-called-once 作为一部分 O1

    考虑所有一次调用的静态函数以内联到其调用程序中,即使它们未标记为内联也是如此。如果集成了对给定函数的调用,则该函数本身不会作为汇编代码输出。

另一方面,您可以告诉编译器不要内联函数(-fno-inline):

除了标有always_inline属性的功能外,请勿展开任何内联功能。这是未优化时的默认设置。
通过使用noinline属性标记单个函数,可以免除它们的内联。