Подтвердить что ты не робот

Можно ли привести GCC в бесконечный цикл?

Можно ли привести GCC в бесконечный цикл, введя странный исходный код? И если да, то как? Может быть, можно что-то сделать с помощью шаблона метапрограммирования?

4b9b3361

Ответ 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) Он не сообщает точную версию компилятора, где это произошло. Я предполагаю, что новые компиляторы обнаруживают случай.