Можно ли привести GCC в бесконечный цикл? - PullRequest
12 голосов
/ 12 марта 2010

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

Ответы [ 7 ]

11 голосов
/ 12 марта 2010

Да.

Почти у каждой компьютерной программы есть проблемы с завершением цикла. Однако я думаю, что в GCC не хватило бы оперативной памяти, прежде чем бесконечный цикл станет очевидным. В его дизайне не так много «свободных» операций.

Парсер и препроцессор не будут создавать проблем. Готов поспорить, что вы могли бы настроить таргетинг на оптимизатор, который, вероятно, будет иметь больше ошибок при реализации. Это будет не столько язык, сколько использование уязвимости, которую вы можете обнаружить из исходного кода. то есть эксплойт был бы неочевиден.

UPDATE

В этом конкретном случае моя теория кажется верной. Компилятор продолжает выделять оперативную память, а оптимизатор кажется уязвимым. Ответ - да. Да, вы можете.

7 голосов
/ 19 марта 2010

Ошибки являются особенно временными, например, ответ @ 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;
}
4 голосов
/ 19 марта 2010

Поскольку метапрограммирование шаблона C ++ фактически завершено, вы можете выполнять бесконечную компиляцию.

Например:

template<typename T>
struct Loop {
   typedef typename Loop<Loop<T> >::Temp Temp;
};

int main(int, char**) {
   Loop<int> n;
   return 0;
}

Впрочем, как и ответ передо мной. У gcc есть флаг, чтобы остановить это от бесконечного продолжения (очень похоже на переполнение стека в бесконечной рекурсии).

1 голос
/ 12 марта 2010

Это может быть возможно. Но большинство компиляторов (и большинство стандартизированных языков) имеют ограничения на такие вещи, как глубина рекурсии в шаблонах или включаемых файлах, после чего компилятор должен выручить с диагностикой. Компиляторы, которые этого не делают, обычно не популярны среди пользователей.

0 голосов
/ 14 марта 2010

Бентли пишет в своей книге «Программирование жемчужин», что следующий код привел к бесконечному циклу во время оптимизированной компиляции:

void traverse(node* p) {
  traverse(p->left);
  traverse(p->right);
}

Он говорит, что «оптимизатор попытался преобразовать хвостовую рекурсию в цикл и умер, когда смог найти тест для завершения цикла». (с.139) Он не сообщает точную версию компилятора, где это произошло. Я предполагаю, что новые компиляторы обнаружат случай.

0 голосов
/ 12 марта 2010

Не знаю о gcc, но старый pcc раньше входил в бесконечный цикл, компилируя некоторые виды бесконечных циклов (те, которые компилировались в _x: jmp _x).

0 голосов
/ 12 марта 2010

Я думаю, вы могли бы сделать это с помощью # include

Просто #include "file1.c" в file2.c и #include "file2.c" в file1

предложение заставляет компилятор многократно зацикливаться, а затем завершаться с ошибкой, а не зацикливаться бесконечно

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...