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