Действительно ли возможно принести GCC в бесконечный цикл путем ввода странного исходного кода? И если да, как? Возможно, можно было сделать что-то с Шаблонным Метапрограммированием?
Ошибки особенно быстротечны, например, ответ @Pestilence был найден в GCC 4.4.0 и исправлен в 4.4.1. Список текущих способов довести GCC до бесконечного цикла можно найти в их Bugzilla.
EDIT: Я только что нашел новый способ, который также приводит к краху Comeau. Это более удовлетворительный ответ, на данный момент. Конечно, это также должно быть исправлено в ближайшее время.
template< int n >
struct a {
a< n+1 > operator->() { return a< n+1 >(); }
};
int main() {
a<0>()->x;
}
Не знаю о gcc, но старый pcc входил в бесконечный цикл, компилируя некоторые виды бесконечных циклов (те, которые компилировались до _x: jmp _x).
Возможно, это возможно. Но большинство компиляторов (и большинство стандартизованных языков) имеют ограничения на такие вещи, как глубина рекурсии в шаблонах или включаемых файлах, и в этот момент компилятор должен выполнить диагностику. Компиляторы, которые этого не делают, обычно не пользуются популярностью у пользователей.
Думаю, вы могли бы сделать это с помощью #include
Просто #include "file1.c" в file2.c и #include "file2.c" в предложении file1
компилятор часто зацикливается, а затем выходит из строя, а не зацикливается бесконечно
Да.
Почти каждая компьютерная программа имеет проблемы с завершением цикла. Я думаю, что gcc, однако, исчерпает оперативную память, прежде чем бесконечный цикл когда-либо станет очевидным. В его дизайне не так много «свободных» операций.
Парсер и препроцессор не создадут проблем. Я готов поспорить, что вы можете ориентироваться на оптимизатор, который, вероятно, будет иметь больше ошибок реализации. Речь пойдет не столько о языке, столько об использовании недостатка, который вы можете обнаружить в исходном коде. т.е. эксплойт будет неочевидным.
UPDATE
В этом конкретном случае моя теория кажется правильной.Компилятор продолжает выделять оперативную память, и оптимизатор кажется уязвимым. Ответ – да. Да, Вы можете.
Бентли пишет в своей книге «Жемчужины программирования», что следующий код привел к бесконечному циклу во время оптимизированной компиляции:
void traverse(node* p) {
traverse(p->left);
traverse(p->right);
}
Он говорит, что «оптимизатор пытался преобразовать хвостовую рекурсию в цикл и умереть, когда он смог найти тест для завершения цикла ». (стр.139) Он не сообщает точную версию компилятора, где это произошло. Я предполагаю, что более новые компиляторы обнаружат этот случай.
Поскольку метапрограммирование шаблонов C ++ на самом деле завершено по Тьюрингу, вы можете сделать бесконечную компиляцию.
Например:
template<typename T>
struct Loop {
typedef typename Loop<Loop<T> >::Temp Temp;
};
int main(int, char**) {
Loop<int> n;
return 0;
}
Однако вроде ответ передо мной. У gcc есть флаг, чтобы это не продолжалось бесконечно (подобно переполнению стека в бесконечной рекурсии).