内联无限递归
Inlining infinite recursion
这是代码定义的行为吗?
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]
)而有所不同。
当然,我认为如果你从不调用这个函数,根据好像规则,编译器可以完全省略它,那么你就没有问题了。
相关文章:
- 交换运算符 + 重载会导致无限递归
- 为什么当函数参数未定义为常量引用时存在无限递归?
- 递归应用 C++20 范围适配器会导致编译时无限循环
- 为什么这个递归函数会创建一个无限循环?
- 计算递归和时的无限循环
- 为什么这是无限递归
- C 递归函数无限循环
- 尝试"复制"shared_ptr向上转换行为会导致复制构造函数上的无限递归(导致段错误)
- ConstexPR模板功能的无限递归
- 交换和移动无限递归
- 无限循环与无限递归.两者都未定义吗?
- 函数中的无限递归
- 无限模板递归,因为没有布尔表达式优化,只有 gcc
- 运算符重载流提取运算符 (>>) C++会导致无限递归流提取
- C 无限环路:递归函数
- 实现递归函数,避免由 C++ 中 include 的循环调用(没有 #pragma 一次)引起的无限循环输入
- C :Ostream无限递归
- 无限递归模板实例化使用clang时GCC工作正常
- 当我使用 boost 构建绝对路径时,无限递归
- 模板中的无限递归