首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

如果函数在C++中内联失败,则不要编译

在C++中,内联函数是一种特殊的函数,它的定义通常放在头文件中,并且在调用处会被直接展开,而不是通过函数调用的方式执行。内联函数的目的是为了提高程序的执行效率,减少函数调用的开销。

然而,有时候编译器可能会选择不将函数内联,这种情况下可以称为内联失败。以下是一些可能导致内联失败的情况:

  1. 函数体过于复杂:如果函数体过于复杂,包含大量的代码逻辑、循环或递归调用等,编译器可能会认为将其内联展开会导致代码膨胀,影响程序的执行效率,因此选择不内联。
  2. 函数体不可见:如果函数的定义不在调用处的可见范围内,编译器无法将其内联展开。例如,函数定义在另一个源文件中,或者是通过库文件提供的函数。
  3. 函数体包含虚函数调用:虚函数是在运行时动态绑定的,编译器无法确定具体调用哪个函数,因此无法将其内联展开。
  4. 函数体包含递归调用:递归调用是函数直接或间接地调用自身,编译器无法将其内联展开。

当函数内联失败时,编译器会将其作为普通函数进行编译和链接。这意味着函数调用会产生额外的开销,包括函数栈帧的创建和销毁,参数的传递等。因此,如果函数的执行频率较高,内联失败可能会导致程序的性能下降。

在实际开发中,我们可以通过以下方式来尝试解决内联失败的问题:

  1. 优化函数体:如果函数体过于复杂,可以尝试优化代码逻辑,减少循环或递归调用的次数,以提高内联的可能性。
  2. 将函数定义放在头文件中:将函数定义放在头文件中,可以使函数在调用处可见,增加内联的机会。
  3. 使用内联函数的关键字:在函数声明和定义处使用关键字inline,可以提示编译器将函数内联展开。
  4. 考虑使用宏替代函数:宏在预处理阶段会直接进行文本替换,可以避免函数调用的开销,但需要注意宏的使用方式和潜在的副作用。

总结起来,内联函数在C++中是一种提高程序执行效率的方式,但并不是所有函数都适合内联展开。当函数在C++中内联失败时,我们可以通过优化函数体、调整函数定义位置、使用内联函数关键字或考虑使用宏等方式来尝试解决内联失败的问题。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

C++内联函数 ④ ( C++ 编译优化 - 没有 inline 关键字修饰的函数也可能被内联 | C++ 编译内联限制 | 内联失败的几种情况 )

来决定的 ; 不能保证所有函数都会被内联 ; 即使函数内联 , 也不能保证 程序的性能 一定会提高 ; 2、C++ 编译器的内联优化 简单且频繁调用的函数 内联大概率成功 , 复杂的函数 大概率内联失败...; 编译决定是否内联函数时 , 会考虑函数的复杂性 , 大小和调用次数等因素 ; 如果 函数比较简单 且被频繁调用 , 编译器可能会选择将其内联 , 以提高程序的执行效率 ; 二、C++ 编译内联限制...1、内联失败的几种情况 内联失败的几种情况 : 如果 内联函数 有如下情况 , 即使使用 inline 关键字声明内联函数 , 也是无效的 ; 函数存在循环 : 内联函数 不能存在任何形式的 循环语句..., 内联直接失败 ; 内联函数声明调用之后 : 由于内联函数不能进行声明操作 , 内联函数的声明与定义必须在一起 , 如果内联函数调用在声明定义之前 , 说明该内联函数进行了单独的声明 , 该函数内联一定会失败..., 作为普通函数处理 ; 2、内联失败的本质分析 函数 如果 有循环语句 / 有很多条件判定语句 / 函数体庞大 / 对函数取地址操作 / 单独声明内联函数 , 即使写了 inline 内联函数 ,

30630

C++:04---内联函数

”,宏C++基本是被废了,书《高质量程序设计指南——C++/C语言》这样解释到: ?...编译调用点内联展开函数的代码时,必须能够找到 inline 函数的定义才能将调用函数替换为函数代码,而对于头文件仅有函数声明是不够的。...头文件中加入或修改 inline 函数时,使用了该头文件的所有源文件都必须重新编译。 8. 慎用内联如果所有的函数都是内联函数,还用得着“内联”这个关键字吗?...要当心构造函数和析构函数可能会隐藏一些行为,如“偷偷地”执行了基类或成员对象的构造函数和析构函数。所以不要随便地将构造函数和析构函数的定义放在类声明。”...————《高质量程序设计指南——C++/C语言》 林锐 而在Google C++编码规范规定得更加明确和详细: 内联函数: Tip:只有当函数只有 10 行甚至更少时才将其定义为内联函数.

1.3K40
  • C++入门----类和对象以及几个关键字的使用

    概念:以inline修饰的函数叫做内联函数编译C++编译器会在调用内联函数的地方展开,没有函数调 用建立栈帧的开销,内联函数提升程序运行的效率。...内联函数的使用场景:一个项目中一个函数经常被调用而且代码量很小,这时我们就可以将其用inline修饰成内联函数,但是内联函数计算机,到底用了inline之后是不是内联函数,这个取决于编译器,这个权限时编译器决定的...假如这个权限给了使用者的话,当我们使用内联函数时,假设调用者滥用,将会使一个原本只需要几kb的文件最后编译出来会比原来大的多,因为inline修饰的函数是不会建立栈帧的,如果函数内部的代码量特别大,调用时用了内联函数...,在编译过程中会使代码特别大 内联函数的特性 inline是一种以空间换时间的做法,如果编译器将函数当成内联函数处理,在编译阶段,会 用函数体替换函数调用,缺陷:可能会使目标文件变大,优势:少了调用开销...,所以C++引入了类和对象的概念 类的引入 C语言结构体只能定义变量,C++,结构体内不仅可以定义变量,也可以定义函数

    5610

    五、从C语言到C++(五)

    如果你需要修改迭代器(例如,遍历过程删除元素),那么你可能需要使用传统的迭代器循环。 函数 从C语言过渡到C++时,函数的概念在很多方面是相似的,但C++函数提供了更多的特性和灵活性。...a : b; } 内联函数的作用 内联函数(Inline Functions)C++主要起到以下作用: 减少函数调用的开销:当函数被声明为内联时,编译器会尝试调用点将函数体直接插入,而不是进行常规的函数调用...如果内联函数包含这些复杂的控制语句,编译器通常会将其视为普通函数处理,不进行内联展开。...默认参数(Default Parameters) C++,可以为函数参数提供默认值。如果在调用函数时没有提供这些参数的值,使用默认值。这在C语言中是不可能的。...以下是关于默认参数的详细解释: 定义与使用: 默认参数指的是函数声明时给函数参数指定一个默认值。 如果调用函数时没有给这个参数传入实参,使用默认值;如果传入了实参,替换掉默认值。

    7510

    我的C++奇迹之旅:内联函数和auto关键推导和指针空值

    +函数声明前增加inline 关键字来告诉编译器这个函数内联函数: inline int Add(int a, int b) { return a + b; } 以inline修饰的函数叫做内联函数...,编译C++编译器会在调用内联函数的地方展开,没有函数调用建立栈帧的开销,内联函数提升程序运行的效率。...这是反汇编对比图: 查看内联函数inline方式 查看内联函数的方式确实需要根据编译模式的不同而采取不同的方法: Visual Studio 2019 ,查看内联函数的步骤如下: Debug...如果没有定义,执行下面的代码块。 #ifdef __cplusplus//这个预处理指令检查是否 C++ 编译环境下。如果C++ 编译环境,执行下面的代码块。...这是因为 C++ ,0 可以隐式转换为任何指针类型,所以将 NULL 定义为 0 是合理的 #else//如果不是 C++ 编译环境,执行这个代码块。

    16710

    C++inline函数简介

    5.inline函数的注意事项 了解了内联函数的优缺点,使用内联函数时,我们也要注意以下几个事项和建议。 (1)使用函数指针调用内联函数将会导致内联失败。...也就是说,如果使用函数指针来调用内联函数,那么就需要获取inline函数的地址。如果要取得一个inline函数的地址,编译器就必须为此函数产生一个函数实体,那么就内联失败。...(6)如何查看函数是否被内联处理了? 实际VS2012预处理了一下,查看预处理后的.i文件,inline函数内联处理不是预处理阶段,而是在编译阶段。...编译源文件为汇编代码或者反汇编查看有没有相关的函数调用call,如果没有就是被inline了。具体可以参考here。 (7)C++类成员函数定义类体内为什么不会报重定义错误?...如果编译器发现被定义类体内的成员函数无法被内联处理,也不会出现重定义的错误,因为C++存在5种作用域的级别,分别是文件域(全局作用域)、命名空间域、类域、函数作用域和代码块作用域(局部域)。

    2.1K20

    Google C++编程风格指南(四)之类的相关规范

    类是C++基本的代码单元,自然被广泛使用。本节列举了写一个类时要做什么、不要做什么。 1....2) 操作失败会造成对象初始化失败,引起不确定状态。 3) 构造函数内调用虚函数,调用不会派发到子类实现,即使当前没有子类化实现,将来仍是隐患。...(2)一般情况下,应该避免构造函数和析构函数调用虚函数如果一定要这样做,程序猿必须清楚,这是对虚函数的调用其实是实调用。可参考博客:C++不要在构造函数和析构函数调用虚函数。...其原因主要有一下两点: (a)如果析构函数抛出异常,异常点之后的程序不会执行,如果析构函数异常点之后执行了某些必要的动作比如释放某些资源,这些动作不会执行,会造成诸如资源泄漏的问题。...参考拷贝构造函数。 .cc文件函数的定义应尽可能和声明次序一致。 不要将大型函数内联到类的定义,通常,只有那些没有特别意义的或者性能要求高的,并且是比较短小的函数才被定义为内联函数

    87421

    C++入门】内联函数、auto与基于范围的for循环

    1.内联函数 1.1内联函数概念 以inline修饰的函数叫做内联函数编译C++编译器会在调用内联函数的地方展开,没有函数调用建立栈帧的开销,内联函数提升程序运行的效率。...内联函数通常在函数定义处使用关键字inline进行声明,例如: inline int add(int a, int b) { return a + b; } 使用内联函数时,编译器会将函数的代码直接插入到调用处...1.2内联函数特点 inline是一种以空间换时间的做法,如果编译器将函数当成内联函数处理,在编译阶段,会用函数体替换函数调用: 缺陷:可能会使目标文件变大 ; 优势:少了调用开销,提高程序运行效率...f@@YAXH@Z),该符号函数 _main 中被引用 结果如下: 上述例子可以发现内联函数声明定义最好不要分离,否则会出现链接错误; 总而言之,内联函数是一种编程技术,可以用于提高函数调用的效率...5.结语 以上就是有关C++入门内联函数、auto关键字、基于范围的for循环以及nullptr所有有关的内容啦~ 完结撒花 ~

    14210

    c++函数探幽笔记

    1.1 c++内联函数 概念:内联函数c++为提高程序运行速度的一项改进。内联函数编译器将使用相应的函数代码替换函数调用。   对于内联代码,程序无需跳到另一个位置处执行代码,再跳回来。...因此,内联函数的运行速度比常规函数稍快,但代价是需要占用更多的内存。 内联函数和常规函数的对比 使用内联函数: 函数声明前加上关键字inline。 函数定义前加上关键字inline。...必须通过原型函数,由于编译器通过查看原型来了解函数所使用的参数数目,因此函数原型也必须将可能的默认参数告知程序。方法就是将值赋给原型的参数。...例如,left( )函数原型如下: char * left(const char * str,int n=1); (用户使用的时候,如果只输入了第一个参数,则按照默认n=1;如果用户输入了第二个参数...(编译器就是根据函数的参数列表的不同,确定重载哪一个函数。虽然函数重载很吸引人,但也不要滥用。

    36320

    CC++inline用法详解

    (一)inline函数(摘自C++ Primer的第三版) 函数声明或定义函数返回类型前加上关键字inline即把min()指定为内联。      ...所以不要随便地将构造函数和析构函数的定义体放在类声明。 一个好的编译器将会根据函数的定义体,自动地取消不值得的内联(这进一步说明 了inline 不应该出现在函数的声明)。...C++ 语言支持函数内联,其目的是为了提高函数的执行效率(速度)。 C程序,可以用宏代码提高执行效率。宏代码本身不是函数,但使用起来象函数。...让我们看看C++ 的"函数内联"是如何工作的。 对于任何内联函数编译符号表里放入函数的声明(包括名字、参数类型、返回值类型)。...如果编译器没有发现内联函数存在错误,那么该函数的代码也被放入符号表里。 调用一个内联函数时,编译器首先检查调用是否正确 (进行类型安全检查,或者进行自动类型转换,当然对所有的函数都一样)。

    1.8K30

    C++C++基础语法

    调用该函数时,如果没有指定实 参采用该形参的缺省值,否则使用指定的实参。...,当参数类型不同的时候,我们需要再去写一个函数,而且还不能同名,如果重名,编译器不会通过,但如果C++,就可以使用,这叫做 函数重载。...以 inline 修饰 的函数叫做内联函数编译C++ 编译器会在 调用内联函数的地方展开 ,没有函数调 用建立栈帧的开销,内联函数提升程序运行的效率。 ​​​​​​​...首先当然不是,内联针对的是,代码少,但是需要经常调用,而且,你加了内联,只是像编译器说明,发出的一个请求,具体编译器要不要展开,人家自己考虑,可以忽略你这个请求!...总结: inline是一种 以空间换时间的做法,如果编译器将函数当成内联函数处理, 编译阶段,会 用函数体替换函数调用,缺陷:可能会使目标文件变大,(编译好的指令影响的是可执行文件的大小

    1.4K20

    小朋友学C++(20):内联函数

    大多数的机器上,调用函数都要做很多工作:调用前要先保存寄存器,并在返回时恢复,复制实参,程序还必须转向一个新位置执行 C++中支持内联函数,其目的是为了提高函数的执行效率,用关键字 inline 放在函数定义...(注意是定义而非声明)的前面即可将函数指定为内联函数内联函数通常就是将它在程序的每个调用点上“内联地”展开,假设我们将 max 定义为内联函数,即上面第(3)种方式,那么若调用的代码为 cout <...< max(a, b) << endl; 编译时,会自动展开为 cout b ?...结论: 一个较为合理的经验准则是, 不要内联超过 10 行的函数. 谨慎对待析构函数, 析构函数往往比其表面看起来要更长, 因为有隐含的成员和基类析构函数被调用!...(递归调用堆栈的展开并不像循环那么简单, 比如递归层数在编译时可能是未知的, 大多数编译器都不支持内联递归函数)。

    37620

    内联函数 c-浅谈内联函数与宏定义的区别详解

    如果是普通函数MAX(a,"HellO")会受到函数调用的检查,但此处不会因为两个参数类型不同而被编译拒之门外。...文章(二)   8.5.1 用内联取代宏代码   C++ 语言支持函数内联,其目的是为了提高函数的执行效率(速度)。    C程序,可以用宏代码提高执行效率。宏代码本身不是函数,但使用起来象函数。...对于任何内联函数编译符号表里放入函数的声明(包括名字、参数类型、返回值类型)。如果编译器没有发现内联函数存在错误,那么该函数的代码也被放入符号表里。...调用一个内联函数时,编译器首先检查调用是否正确(进行类型安全检查,或者进行自动类型转换,当然对所有的函数都一样)。如果正确,内联函数的代码就会直接替换函数调用,于是省去了函数调用的开销。...所以不要随便地将构造函数和析构函数的定义体放在类声明。   一个好的编译器将会根据函数的定义体,自动地取消不值得的内联(这进一步说明了inline不应该出现在函数的声明)。

    67740

    C++C++入门

    (带有缺省参数)函数的定义和声明 a. 带有缺省参数的函数定义和声明时,C++有特殊的规定,函数的声明部分写出缺省参数,函数的定义部分不写缺省参数,如下面代码所示。 b....下面的两个函数C++是支持同时存在的,但在C语言中是不支持的。...这时候,C++中就提出了内联函数内联函数编译 ) 期间,编译器会用函数体来替换内联函数的调用,而不是宏那样的单纯替换 #define ADD(x,y) x+y #define ADD(x,y...如果不是内联函数还频繁调用的话,就会频繁的开辟函数栈帧,这会对程序产生不小的开销,影响程序运行时的效率,内联函数不害怕这一点,因为它根本就不建立函数栈帧 同时如果内联函数体过大,编译器也会将主动权掌握自己手里...结论:内联函数定义时不要搞到.c文件里定义了,直接在.h文件里面定义就好,不要把定义和声明分开,这样展开.h文件之后,函数体就在那里,链接阶段就不会在去找函数的地址了,因为函数就在他自身的目标文件里面

    2.8K30

    Google C++编程风格指南(二)之函数的相关规范

    内联较短小的存取函数通常会减少代码量,但内联一个较大的函数(注:如果编译器允许的话)将显著增加代码量。...使用inline函数应该遵循以下几点: (1)内联函数最好不要超过10行; (2)对于析构函数应慎重对待,析构函数往往比其表面看起来要长,因为有一些隐式成员和基类析构函数如果有的话)被调用; (3...(5)如果对析构函数内联,主要原因是类体重定义,为了方便抑或是其他原因,应对其行为给出文档说明。...2.2不要设计多用途面面俱到的函数 多功能集于一身的函数,很可能使函数的理解、测试、维护等变得困难。 应编写功能单一集函数。...在对这些共享变量进行访问时,如果要保证线程安全,必须通过加锁的方式。

    91120

    C++入门

    调用该函数时,如果没有指定实参采用该形参的缺省值,否则使用指定的实参 void Func(int a = 0){cout<<a<<endl;}int main(){Func(); // 没有传参时,...,声明和定义分离情况下,应当把缺省参数函数声明给出缺省值必须是常量或者全局变量C++函数重载实际开发,有时候我们需要实现几个功能类似的函数,只是有些细节不同。...而C++是通过函数修饰规则来区分,只要参数不同,修饰出来的名字就不一样,就支持了重载。如果两个函数函数名和参数是一样的,返回值不同是不构成重载的,因为调用时编译器没办法区分。...内联函数以inline修饰的函数叫做内联函数编译C++编译器会在调用内联函数的地方展开,没有函数调用建立栈帧的开销,内联函数提升程序运行的效率 。...如果使用 auto 关键字,编译器就无法确定参数的类型,只有调用函数的时候,才能根据实参来推导出形参的类型,否则就会导致编译错误。

    18620

    C++基础——函数

    默认参数 C++可以函数声明时为参数提供一个默认值,当函数调用时没有指定这个参数的值,编译器会自动用默认值代替一旦一个函数调用开始使用默认参数值,那么这个参数后的所有参数都必须使用默认参数 void...结果是编译器并不会报错,因为它并不知道你的目的是重写虚函数,而是把它当成了新的函数如果这个虚函数很重要的话,那就会对整个程序不利。...使用时,定义基类类型的指针,使其指向派生类的对象,使用该指针调用某个方法,若该方法未被声明为虚函数调用的是指针类的方法,若该方法是虚函数调用的是指针指向对象类的该方法。...虚函数使用原则: 1)当类不会用作基类时,成员函数不要声明为virtual 2)当成员函数不重新定义基类的方法,成员函数不要声明为virtual inline内联函数   内联函数编译器处理,直接将编译后的函数体插入调用的地方...C++内联编译的限制: 1.不能存在任何形式的循环语句 2.不能存在过多的条件判断语句 3.函数体不能过于庞大 4.不能对函数进行取址操作 5.函数内联声明必须在调用语句之前。

    61640

    C++ 类使用规范建议

    类是 C++ 基本的代码单元,被广泛使用。本节列举了写一个类时要做什么、不要做什么。 1....(2)操作失败会造成对象初始化失败,引起不确定状态。 (3)构造函数内调用虚函数,调用不会派发到子类实现,即使当前没有子类实现,将来仍是隐患。...(2)一般情况下,应该避免构造函数和析构函数调用虚函数如果一定要这样做,程序猿必须清楚,这时对虚函数的调用其实是实调用。可参考博客:C++不要在构造函数和析构函数调用虚函数。...其原因主要有一下两点: (3.1)如果析构函数抛出异常,异常点之后的程序不会执行,如果析构函数异常点之后执行了某些必要的动作比如释放某些资源,这些动作不会执行,会造成诸如资源泄漏的问题。...不要将大型函数内联到类的定义,通常,只有那些没有特别意义的或者性能要求高的,并且是比较短小的函数才被定义为内联函数。 13.

    1.8K20

    Google C++ 编程风格指南:头文件

    如果 .h 文件声明了一个模板或内联函数,同时也该文件加以定义。凡是有用到这些的 .cc 文件,就得统统包含该头文件,否则程序可能会在构建中链接失败。...有个例外:如果函数模板为所有相关模板参数显式实例化,或本身就是某类的一个私有成员,那么它就只能定义实例化该模板的 .cc 文件里。 1.2....结论: 一个较为合理的经验准则是, 不要内联超过 10 行的函数. 谨慎对待析构函数, 析构函数往往比其表面看起来要更长, 因为有隐含的成员和基类析构函数被调用!...有些函数即使声明为内联的也不一定会被编译内联, 这点很重要; 比如虚函数和递归函数就不会被正常内联. 通常, 递归函数不应该声明成内联函数.... #include 插入空行以分割相关头文件, C 库, C++ 库, 其他库的 .h 和本项目内的 .h 是个好习惯。

    77230

    C++内联函数&auto&范围for循环&nullptr

    2.范围for的使用条件 指针空值nullptr(C++11) 1.C++98的指针空值 内联函数 1.概念 以inline修饰的函数叫做内联函数编译C++编译器会在调用内联函数的地方展开,没有函数调用建立栈帧的开销...C语言中,我们为了减少栈帧的开销,我们可以通过宏函数,没有栈帧消耗,预处理的阶段就被替换了,就没有栈帧的消耗了 (比如频繁调用小函数的时候) 而在C++,我们是通过inline内联函数解决这个问题的...不是说内联函数会展开吗,不建立函数的栈帧,这里为什么会建立❓ 这是因为Debug版本下内联函数是不会展开的(因为Debug版本下我们可以进行调试) 查看方式: release模式下,查看编译器生成的汇编代码是否存在...inline对于编译器而言只是一个建议,编译器会自动优化,如果定义为inline的函数体内有循环/递归等等,编译器优化时会忽略掉内联。 inline不建议声明和定义分离,分离会导致链接错误。...C++98,字面常量0既可以是一个整形数字,也可以是无类型的指针(void*)常量,但是编译器默认情况下将其看成是一个整形常量,如果要将其按照指针方式来使用,必须对其进行强转(void *)0。

    69230
    领券