Infinite compilation with templates

核能气质少年 提交于 2019-12-30 06:47:28

问题


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)


回答1:


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)).




回答2:


Getting the parser into an infinite loop using template is not new.

// 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;



回答3:


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.




回答4:


Should not be compiler smart enough to stop at some time ?

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:

template<>
struct Infinite<100> //this is to stop template with <I+1> argument
{
  enum { value = 678678 }; //see, it doesn't use Infinite<> any further!
};

template<>
struct Infinite<-100> //this is to stop template with <I-1> argument
{
  enum { value = -67878 }; //see, it too doesn't use Infinite<> any further!
};


来源:https://stackoverflow.com/questions/6079603/infinite-compilation-with-templates

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!