首页 > 编程语言 >C++ inline

C++ inline

时间:2022-08-30 08:36:29浏览次数:49  
标签:调用 函数 inlining C++ 编译器 inline

1.inline可以免除函数调用时的保存上下文时的一些开销,其本质就是对此函数的每一个调用都以函数本体替换之。

 

inline的坏处:若在一台内存有限的机器上,过度热衷inlining会造成程序体积太大,即使拥有虚拟内存,inline造成的代码膨胀也会导致额外的换页行为,降低指令高速缓存装置的集中率,以及伴随这些而来的效率。

但是好处是,如果inline函数的本体很小,编译器针对函数本体所产出的码可能比函数调用所需要的开销等所产出的码更小。那么inlining函数可以导致较小的目标码和较高的指令告诉缓存装置击中率。

 

inline只是对编译器的一个申请,不是强制命令。这项申请可以隐喻提出,也可以明确提出。

隐喻方式

 

class person{
    public:
    int age() const {return theAge;}
    private:
    int theAge;
}

这样的函数通常是成员函数。

 

 

明确方式

template<typename T>
inline const T& std::max(const T& a, const T& b){
    return a<b?b:a;
}

有关键字在开头。

 

使用inline后,编译器会根据代码来判断是否可以inlining,inlining在大多数C++程序中是编译期行为。非常少部分是运行期行为。

2.inline是个申请,编译器可加以忽略。大部分编译器拒绝将太过复杂(例如带有循环或递归)的函数inlining,而对所有虚函数(除非是最平淡无奇的)也都会使得inlining落空。因为virtual意味着“等待,直到运行期才确定调用哪个函数”,而inline意味着执行前,先将动作替换为被调用函数的本体。如果编译器不知道该调用哪个函数,则没办法将函数本体inlining。

与此并提的是,编译器通常不对“通过函数指针而进行的调用”实施inlining,这意味着对inline函数的调用有可能被inlined,也可能不被inlined,取决于实施方式。

 

inline void f() {...}
void (*pf) () = f;
​
...
f(); //将被调用,其是一个正常调用
pf(); //这个或许不被调用,因为它通过函数指针达成

 

 

 

3.最后,如果想inline类的构造函数,析构函数得再三考虑。因为C++对于“对象被创建和被销毁时发生了什么事”做了各式各样的保证。当你使用new,动态创建的对象被其构造函数自动初始化;当你使用delete,对应的析构函数会被调用。当你创建一个对象,其每一个base class以及每一个成员变量都会被自动构造;当你消费一个对象时,反向程序的析构行为也会自动发生。如果有个异常在对象构造期间被抛出,该对象已构造好的那一部分也会被自动销毁。在这些情况中C++描述了什么一定会发生,但没有说如何发生。事情如何发生事由编译器实现者的权责,不过至少有一点很清楚,那就是他们不可能凭空发生。在你的程序内一定有某些代码能让那些事情发生,而那些代码——由编译器于编译期间代为产生并安插到你的程序中的代码——肯定存在某个地方,有时候就放在你的构造函数和析构函数内。

 

 

实际上的Derived()

 

 

 

4.inline函数本质上是将代码在编译期间写入调用函数内,故如果被inline的函数f()更改,那么调用过f()的函数都得重新编译。这是一个大问题,需要考虑。而被调用的函数如果是以正常的头文件调用形式的话(即non_inlined)那么只要修改头文件,重新链接库即可。

标签:调用,函数,inlining,C++,编译器,inline
From: https://www.cnblogs.com/lbqverdent/p/16638034.html

相关文章

  • C/C++家谱管理系统
    C/C++家谱管理系统题目B5:基于角色管理的简易家谱管理系统(一)课题内容家谱管理系统是查询家谱信息必不可少的一部分,利用家谱管理系统可以清楚的了解家族成员信息。该......
  • C++外卖点餐系统
    C++外卖点餐系统设计并实现一个外卖点餐系统。至少为该系统设计两个类,菜品类Food和订单类Order。需要完成如下功能:1、菜品Food类的属性包括:菜品代码,菜品名称,菜品价格,折扣......
  • 【C++】delete
    delete是根据指针的类型来调用析构的。当delete派生类对象填充的派生类指针,那么delete这个指针,先调用派生类析构,再调用基类析构。当多态环境下,delete指向派生类对象的基类......
  • # 关于C++20Concept(概念)及requires表达式的学习
    关于C++20Concept(概念)及requires表达式的学习Concept(概念)C++20引入了concept以在编译期检查模板实参是否满足指定的约束.如何不用concept进行约束template<typenam......
  • C++性能优化指南 pdf
    高清扫描版下载链接:https://pan.baidu.com/s/1Gwc_yVHcJY6trqNodDXLpA点击这里获取提取码《C++性能优化指南》是一本C++代码优化指南。作者精选了他在近30年编程生涯中频......
  • C++ 左值于右值的理解
    定义与区别左值(lvalue,locatorvalue)表示了一个占据内存中某个可识别的位置(也就是一个地址)的对象。即左值指的是可以取地址的变量。区分表达式的左右值属性有一个简......
  • CCF 202009-1 称检测点查询(C++)
    使用结构体struct+自定义sort轻松搞定#include<iostream>#include<bits/stdc++.h>#include<cstdio>usingnamespacestd;intn,X,Y;structpoint{......
  • C++【多线程编程】之【线程安全】
    1.线程安全是什么?在拥有共享数据的多条线程并行执行的程序中,线程安全的代码会通过同步机制保证各个线程都可以正常且正确的执行,不会出现数据污染等意外情况。2.什么情况......
  • C++各个版本新增对于算法竞赛有用特性
    C++各个版本新增对于算法有用特性C++11auto与decltype类型推导(摘自程序喵大人)autoauto可以让编译器在编译器就推导出变量的类型,话不多说上代码:autoa=10;//10是in......
  • c++ 在项目中创建DLL,并调用
    创建DLL分为两种方法,先介绍第一种一、创建DLL(1)//dll.h#pragmaonce//dll.h#ifndefDLL_H_#defineDLL_H_voidprinthello();voidcallPython();extern"C"_de......