C++ 内联扩展编译为函数调用[c+;+;] 导言:

C++ 内联扩展编译为函数调用[c+;+;] 导言:,c++,assembly,visual-c++,inline,C++,Assembly,Visual C++,Inline,我一直在创建一个简单的包装类。我随机发现(或者看起来是)一个内联函数仍然编译成函数调用。我创建了一个示例类来进行测试,我发现: 考虑以下类别: //compile with MSVC class InlineTestClass { public: int InternalInt; int GetInt() {return InternalInt;} inline int GetInt_Inl() {return InternalIn

我一直在创建一个简单的包装类。我随机发现(或者看起来是)一个内联函数仍然编译成函数调用。我创建了一个示例类来进行测试,我发现:

考虑以下类别:

//compile with MSVC
class InlineTestClass
{
public:
    int InternalInt;

    int         GetInt()        {return InternalInt;}
    inline int  GetInt_Inl()    {return InternalInt;}                
    //__forceinline -Forces the compiler to implement the function as inline
    __forceinline int  GetInt_ForceInl()  {return InternalInt;} 
};
该类有3个函数可供参考。

//compile with MSVC
class InlineTestClass
{
public:
    int InternalInt;

    int         GetInt()        {return InternalInt;}
    inline int  GetInt_Inl()    {return InternalInt;}                
    //__forceinline -Forces the compiler to implement the function as inline
    __forceinline int  GetInt_ForceInl()  {return InternalInt;} 
};
  • GetInt函数是一个标准函数
  • GetInt\u Inl函数是一个内联函数
  • GetInt\u ForceInl函数是一个确保的内联函数,用于 编译器决定不将GetInt\u Inl作为内联函数实现
这样实施:

InlineTestClass itc;
itc.InternalInt = 3;
int myInt;

myInt = itc.InternalInt;       //No function
myInt = itc.GetInt();          //Normal function
myInt = itc.GetInt_Inl();      //Inline function
myInt = itc.GetInt_ForceInl(); //Forced inline function
myInt设置的结果汇编代码(取自DisAssembler):

这意味着汇编器代码也应该与直接从类成员处设置的代码相同,但事实并非如此

问题:
  • 我是否遗漏了某些内容或功能实现不正确
  • 我在解释内联关键字的功能吗?这是什么
  • 为什么这些内联函数会导致函数调用

  • 默认情况下,类中定义的函数是“推荐的内联函数”。所以内联绝对没有什么作用。此外,编译器总是可以随意否决程序员的关键字。这只是建议

    从C++17草稿(第147页)中:

    内联说明符向实现表明,在调用点对函数体进行内联替换要优于通常的函数调用机制。在调用点执行此内联替换不需要实现;但是,即使省略了此内联替换,也应遵守本款中规定的内联函数的其他规则


    如果编译时没有优化,函数将永远不会内联。从更改编译器选项开始。该函数是使用/Od或/Ob0编译的。在这些情况下,不需要内联。如果您忘记阅读下一段代码,则可以假设
    /Od
    处于启用状态:只有在编译器的成本/收益分析表明插入(称为内联扩展或内联)是有利可图的情况下,才会发生插入(称为内联扩展或内联)。内联扩展以更大的代码大小为潜在成本,减轻了函数调用开销<代码>内联只是建议函数内联。此外:编译器将内联扩展选项和关键字视为建议。无法保证函数将被内联。您不能强制编译器内联特定函数,即使使用_forceinline关键字也是如此。另外:请注意,如果进行调试,MSVC将不会内联。(使用调试器执行非内联调试通常要容易得多)。
    inline int  GetInt_Inl() {return InternalInt; //Is the function body}
    myInt = itc.GetInt_Inl(); //Call site 
    
    //Should result in
    myInt = itc.InternalInt; //Identical to setting from the member directly