2

如果 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 编译器上安全运行,是否有某种宏,或者完全不可能,并且没有办法制作这个示例或任何类似的模式安全吗?

4

1 回答 1

3

在 C99 标准的基本原理,第 24 页,讨论了翻译限制:

该标准要求实现能够翻译和执行满足每个规定限制的某些程序。该标准被认为为实现者在满足这些限制方面提供了有用的自由度。尽管有缺陷的实现可能会设计出满足此要求的程序,但仍会成功地无用,但 C89 委员会认为,这种独创性可能需要更多的工作,而不是使某些有用的东西。C89 和 C99 委员会的意思是,实现者不应将转换限制解释为硬连线参数的值,而应将其解释为判断实现的一组标准。

假设至少存在一个(可能是人为的和无用的)程序,名义上行使给定的翻译限制,并且实现将以与标准一致的方式处理,那么该实现与任何其他程序所做的任何事情都不能使它成为非-符合。因此,任何程序实际上都不可能有意义地避免未定义的行为,但标准的作者预计大多数实现将更多地关注使它们有用的必要条件,而不是试图做标准。

于 2020-11-10T21:17:14.590 回答