内联无限递归

Inlining infinite recursion

本文关键字:递归 无限      更新时间:2023-10-16

这是代码定义的行为吗?

inline int a() { return 0 + a(); }
int main() { a(); }

如果启用了优化,则 Clang 会对其进行优化,但 GCC 不会。因此,代码在实践中是不可移植的。C++规范对此有什么说明吗?

正如我在这个答案中所讨论的,无论是否存在inline关键字,你的代码的行为肯定是未定义的,因为你调用这个函数:

[C++11: 1.10/24]: 实现可能假定任何线程最终都会执行以下操作之一:

  • 终止
  • 调用库 I/O 函数,
  • 访问或修改易失性对象,或
  • 执行同步操作或原子操作。

允许 Clang 省略整个内容,就像 GCC 被允许在不内联的情况下运行它并达到堆栈溢出一样。编译器也可以自由地尝试实际内联,在这种情况下,它甚至允许在编译过程中崩溃。

至关重要的是,标准中没有规则使无限递归的语义仅仅因为函数被标记为inline甚至实际内联([C++11: 7.1.2])而有所不同。

当然,我认为如果你从不调用这个函数,根据好像规则,编译器可以完全省略它,那么你就没有问题了。