使用模板进行无限编译

iam*_*ind 5 c++ compiler-construction recursion templates

这个问题只是出于好奇.在递归模板中如果我们忘记放置一个特定的特化,那么编译器将进行大量的迭代然后在某个时候停止并给出错误,例如,

error: incomplete type ‘X<-0x000000000000001ca>’ used in nested name specifier
Run Code Online (Sandbox Code Playgroud)

在某些情况下,编译是无限的.例如,请参阅以下代码(仅用于说明;使用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;
}
Run Code Online (Sandbox Code Playgroud)

难道编译器不够聪明,不能在某个时候停止吗?

编辑:上面显示的编译错误是针对其他代码的.对于示例代码,编译永远不会停止(但是,我会在两者之间看到这样的错误)

bit*_*ask 8

如果我正确理解您的问题,您希望编译器识别它永远不会停止迭代.除了在固定数量的嵌套类型之后停止之外,你想要的东西显然是不可能的:如果我正确地看到它你可以用这种方式表达任何图灵机(至少模板D是图灵完成的).

因此,如果您可以构建一个识别它将在实际尝试之前永久嵌套类型的编译器,那么您将决定停止问题,这对于图灵机来说是不可判定的.

但是,我很可能会误认为你可以在参数列表中放置任何计算(但是模拟寄存器机器似乎是可能的,因为我们可以在一个单独的整数模板参数中编码所有寄存器(是的,int是有限的,但是相当大,这使它实际上无限制)).


hac*_*rks 6

使用模板将解析器置于无限循环中并不新鲜.

// Stresses the compiler infinitely
// from: http://www.fefe.de/c++/c%2b%2b-talk.pdf
template<class T> struct Loop { Loop<T*> operator->(); };
Loop<int> i, j = i->hooray;
Run Code Online (Sandbox Code Playgroud)