在 C 中可以安全递归吗?
Is safe recursion possible in C?
如果 C 中的堆栈大小是一个实现细节,并且堆栈溢出是未定义的行为,那么有没有可能执行任何递归而不可能召唤鼻子恶魔?
如果我递归地遍历一个数据结构,举一个天真的例子:
struct tree {
int leaf;
struct tree *left;
struct tree *right;
}
struct tree *get(const struct tree *t, int i) {
if (t == NULL) return NULL;
return i == t->leaf ? t : (i > t ? get(t->right) : get(t->left));
}
是否有某种检查可以实现,以便此示例可以 运行 在任何遵循标准的 C 编译器上安全地运行,是否有某种宏,或者它是否完全不可能,以及没有办法让这个例子或任何类似的模式安全吗?
在 C99 标准的基本原理中,第 24 页,讨论翻译限制:
The Standard requires that an implementation be able to translate and execute some program that
meets each of the stated limits. This criterion was felt to give a useful latitude to the
implementor in meeting these limits. While a deficient implementation could probably contrive
a program that meets this requirement, yet still succeed in being useless, the C89 Committee felt
that such ingenuity would probably require more work than making something useful. The sense
of both the C89 and C99 Committees was that implementors should not construe the translation
limits as the values of hard-wired parameters, but rather as a set of criteria by which an
implementation will be judged.
只要存在至少一个——可能是人为设计的和无用的——名义上执行给定翻译限制的程序,并且一个实现将以与标准一致的方式处理,该实现与任何其他程序无关程序可能使其不符合要求。因此,实际上任何程序都不可能有意义地避免未定义的行为,但标准的作者预计大多数实现将更多地关注使它们有用的必要条件,而不是尝试做标准。
如果 C 中的堆栈大小是一个实现细节,并且堆栈溢出是未定义的行为,那么有没有可能执行任何递归而不可能召唤鼻子恶魔?
如果我递归地遍历一个数据结构,举一个天真的例子:
struct tree {
int leaf;
struct tree *left;
struct tree *right;
}
struct tree *get(const struct tree *t, int i) {
if (t == NULL) return NULL;
return i == t->leaf ? t : (i > t ? get(t->right) : get(t->left));
}
是否有某种检查可以实现,以便此示例可以 运行 在任何遵循标准的 C 编译器上安全地运行,是否有某种宏,或者它是否完全不可能,以及没有办法让这个例子或任何类似的模式安全吗?
在 C99 标准的基本原理中,第 24 页,讨论翻译限制:
The Standard requires that an implementation be able to translate and execute some program that meets each of the stated limits. This criterion was felt to give a useful latitude to the implementor in meeting these limits. While a deficient implementation could probably contrive a program that meets this requirement, yet still succeed in being useless, the C89 Committee felt that such ingenuity would probably require more work than making something useful. The sense of both the C89 and C99 Committees was that implementors should not construe the translation limits as the values of hard-wired parameters, but rather as a set of criteria by which an implementation will be judged.
只要存在至少一个——可能是人为设计的和无用的——名义上执行给定翻译限制的程序,并且一个实现将以与标准一致的方式处理,该实现与任何其他程序无关程序可能使其不符合要求。因此,实际上任何程序都不可能有意义地避免未定义的行为,但标准的作者预计大多数实现将更多地关注使它们有用的必要条件,而不是尝试做标准。