如果在 C++ 中内联一个调用 self 的函数会发生什么

Nig*_*eXD 2 c++ visual-c++

首先,我认为编译时间会永远持续下去,或者我遇到一个奇怪的错误,但这并没有发生。代码运行了一段时间然后崩溃了。

这是我的代码:

#include <iostream>

inline void say_hello()
{
    std::cout << "hello\n";
    say_hello();
}

int main()
{
    say_hello();
}

Run Code Online (Sandbox Code Playgroud)

我以为编译器会把它转换成这样的:

#include <iostream>

int main()
{
    std::cout << "hello\n";
    std::cout << "hello\n";
    std::cout << "hello\n";
    std::cout << "hello\n";
    std::cout << "hello\n";
    std::cout << "hello\n";
    std::cout << "hello\n";
    std::cout << "hello\n";
    std::cout << "hello\n";
    std::cout << "hello\n";
    std::cout << "hello\n";
    std::cout << "hello\n";
    std::cout << "hello\n";
    std::cout << "hello\n";
    std::cout << "hello\n";
    // and crash because my storage is filled
}
Run Code Online (Sandbox Code Playgroud)

但是,我认为编译器忽略了该inline关键字。

Joh*_*eau 5

在现代 C++ 中,inline说明符只是向编译器建议您可能想要内联该函数。编译器不需要遵守。

对于您的特定编译器,请参阅Visual Studio 内联函数 (C++)。您似乎“想要”__forceinline将装饰器与#pragma inline_recursion(on). 这将内联到 16 的深度,但这也是可以修改的。我希望大家很清楚为什么这都是一个坏主意。请注意,这是特定于所有编译器的,不适用于 gcc。

__forceinline失败可能有多种原因,但可能适用于您的原因有:

  • 该函数是递归的(你拥有的)并且#pragma inline_recursion(on)未设置
  • 程序是用/Ob0(调试版本的默认值,您可能已经设置)编译的

如果要递归到不同于 16(默认)的级别,可以使用inline_depthpragma 来指定。

你的函数最终看起来像这样(未经测试):

#include <iostream>

#pragma inline_depth(9000)
#pragma inline_recursion(on)
__forceinline void say_hello()
{
    std::cout << "hello\n";
    say_hello();
}

int main()
{
    say_hello();
}
Run Code Online (Sandbox Code Playgroud)