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

What happens if you inline a function that calls it self in C++

起初我以为编译时间会很长,或者我会出现一个奇怪的错误,但那并没有发生。代码运行一段时间就崩溃了

这是我的代码:

#include <iostream>

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

int main()
{
    say_hello();
}

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

#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
}

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

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

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

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

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

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

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

#include <iostream>

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

int main()
{
    say_hello();
}