使用模板进行无限编译
这个问题只是出于好奇。在递归模板中,如果我们忘记放置一个特定的专业化,那么编译器将进行大量迭代,然后在某个时候停止并给出错误,例如,
error: incomplete type ‘X<-0x000000000000001ca>’ used in nested name specifier
在某些情况下,编译会无限。例如,请参阅下面的代码(仅用于说明;使用 gcc 4.4.1 编译):
template<int I>
struct Infinite
{
enum { value = (I & 0x1)? Infinite<I+1>::value : Infinite<I-1>::value };
};
int main ()
{
int i = Infinite<1>::value;
}
编译器不应该聪明到足以在某个时候停止吗?
编辑:上面显示的编译错误是针对其他代码的。对于示例代码,编译永远不会停止(但是,我在中间看到了这样的错误)
This question is just out of curiosity. In recursive templates if we forget to put one particular specialization, then compiler will do large number of iterations and then stop at sometime and gives error such as,
error: incomplete type ‘X<-0x000000000000001ca>’ used in nested name specifier
In certain cases, the compilation goes infinite. For example, see the below code (just for illustration; compiled with gcc 4.4.1):
template<int I>
struct Infinite
{
enum { value = (I & 0x1)? Infinite<I+1>::value : Infinite<I-1>::value };
};
int main ()
{
int i = Infinite<1>::value;
}
Should not be compiler smart enough to stop at some time ?
Edit: The compilation error shown above is for other code. For the sample code, compilation never stops (however, I get to see such errors in between)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
如果我正确理解你的问题,你希望编译器认识到它永远不会停止迭代。除了在固定数量的嵌套类型之后停止之外,您想要的显然是不可能的:如果我没有看错,您可以表达任何
因此,如果您可以构建一个编译器,在实际尝试之前识别出它将永远嵌套类型,那么您就决定了 停止问题 这对于图灵机来说是不可判定的。
但是,我很可能会错误地认为您可以将任何计算放入参数列表中(但模拟寄存器机似乎是可能的,因为我们可以将所有寄存器编码在单独的整数模板参数中(是的,
int
是有限的,但相当大,这使得它实际上是无界的))。If I understand your question correctly, you want the compiler to recognise that it will never stop iterating. Besides just stopping after a fixed number of nesting types, what you want is provably impossible: If I see it correctly you can express any turing-machine in this fashion (at least the templates in
D
are turing complete).So if you can build a compiler that recognises that it will nest types forever before actually trying to, you decide the halting problem which is undecidable for turing-machines.
However, I could very well be mistaken that you can put any computation in the parameter-list (but simulating a register-machine appears to be possible, as we can encode all registers in a separate integer template parameter (yes,
int
is finite, but quite large, which makes it practically unbounded)).使用模板让解析器进入无限循环并不是什么新鲜事。
Getting the parser into an infinite loop using template is not new.
编译器会按照您的要求执行操作。你要求它进行无限递归——它正是这么做的。如果你想让它“在某个时间停止”,你必须要求它在“某个时间”停止,并告诉它你到底指的是哪个具体的“某个时间”。
模板递归与 C++ 程序中的任何其他递归没有什么不同:您有责任指定递归的最低点。
The compiler does what you ask it do do. You asked it to engage into infinite recursion - it did exactly that. If you want it to "stop at some time", you have to ask it to stop at "some time" and tell it what specific "some time" you mean exactly.
Template recursion is not different from any other recursion in C++ program: it is your responsibility to specify where the recursion bottoms-out.
你如何定义“在某个时候”这个短语?编译器如何知道您对“在某个时间”的定义?如果您不明确告诉它,它怎么知道什么时候必须停止?明确您必须首先通过定义不间断类模板的专门化来告诉它(您编写的是不间断类模板)。
在您的情况下,您必须有两种专门化的类模板,每个方向各有一种(递增和递减)。像这样的东西:
How do you define the phrase "at some time"? How would the compiler know your definition of "at some time"? How would it know when it must stop if you don't tell it explicitly? You've to tell it first by defining specialization(s) of the non-stopping class template (what you've written is non-stopping class template).
In your case, you must have two specializations of the class template, one in each directions (increasing, and decreasing). Something like this: