【发布时间】:2019-06-28 17:50:24
【问题描述】:
我知道无限递归或迭代是未定义的行为,但有界不是。但是,对于大多数输入,该程序段都会出错。它是否有未定义的行为,为什么或为什么不?如果它具有未定义的行为,是否可以进行一些修改以消除未定义的行为?
#include <cstdint>
using bigint = ::std::uint64_t;
constexpr const bigint add_val = 1442695040888963407;
constexpr const bigint mult_val = 6364136223846793005;
bigint compute(bigint t)
{
if (t > 1) {
return add_val + compute(t * mult_val);
} else {
return 1;
}
}
int main(int argc, char const * const argv[])
{
return compute(argc < 0 ? -argc : argc);
}
这基本上是使用递归循环遍历 linear congruential random number generator with a period of 2^64 的所有值,因此它保证最终会达到 0 或 1。
我在问一个非常明确和具体的问题。这个任何人都可以编译和运行的程序是否会根据 C++ 标准调用未定义的行为?
【问题讨论】:
-
如果传入的
t大于1,会一直这样直到溢出,不是吗? -
好吧,根据我完全没有受过教育的估计,在参数的值是终止递归的仅有的两个可能值之一之前,我预计大约有 2^63 次递归调用(平均而言)。那么,你有足够的堆栈空间来进行 2^63 次递归调用吗?
-
@SamVarshavchik - 嗯,这取决于我在哪台计算机上运行它,不是吗?我无法访问任何具有足够堆栈空间的计算机。而且我认为现在这个星球上的其他任何人都不会这样做。但这不是我的问题。
-
看起来
t在几乎所有情况下都大于 1。所以会被调用直到溢出 -
我想问题是“标准是否对最大调用堆栈大小施加了限制?”。我怀疑它没有,堆栈溢出是技术上必要的不合规问题。但我不确定。编辑:我能找到的唯一提到的“溢出”是关于整数的,唯一提到的“堆栈”是关于
std::stack和堆栈展开。编辑 2:“递归”的唯一提及是在 “允许递归调用,main函数除外。”.
标签: c++ recursion c++17 undefined-behavior